pyxpo-sharing 0.1.0a1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Vishal Chaubey
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyxpo-sharing
3
+ Version: 0.1.0a1
4
+ Summary: System share sheet for pyxpo apps (react-native Share and expo-sharing shapes).
5
+ Author: Vishal Chaubey
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/pyxpo/pyxpo/tree/main/packages/sharing
8
+ Project-URL: Issues, https://github.com/pyxpo/pyxpo/issues
9
+ Keywords: pyxpo,pyxpo-module,mobile,android,ios
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development :: User Interfaces
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: pyxpo<0.2,>=0.1.0a1
18
+ Dynamic: license-file
19
+
20
+ # pyxpo-sharing
21
+
22
+ System share sheet for pyxpo apps (react-native Share shape).
23
+
24
+ This is an optional [pyxpo](https://github.com/pyxpo/pyxpo) native module. Apps that do not
25
+ list it carry none of its code, permissions or dependencies.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install pyxpo-sharing
31
+ ```
32
+
33
+ Then link it into your app in `pyproject.toml`:
34
+
35
+ ```toml
36
+ [tool.pyxpo]
37
+ modules = ["sharing"]
38
+ ```
39
+
40
+ and rebuild (`pyxpo run ios`, `pyxpo build android`, ...). The build copies the module's Swift and Kotlin
41
+ sources into the native project and its Python package into the app.
42
+
43
+ ## Use
44
+
45
+ ```python
46
+ from pyxpo_sharing import Share
47
+
48
+ await Share.share({"url": path, "message": "Made with pyxpo"})
49
+ ```
50
+
51
+ Permissions and Info.plist keys: none (Android shares through a FileProvider declared in the module manifest).
52
+
53
+ ## What is in the package
54
+
55
+ - `pyxpo_sharing/__init__.py`: the Python API.
56
+ - `pyxpo_sharing/pyxpo-module.json`: autolink metadata (bridge name, Swift and Kotlin classes, Android namespace and dependencies, Info.plist keys).
57
+ - `pyxpo_sharing/ios/`: Swift sources compiled into the iOS app.
58
+ - `pyxpo_sharing/android/src/main/`: Kotlin sources and the manifest merged into the Android app.
@@ -0,0 +1,39 @@
1
+ # pyxpo-sharing
2
+
3
+ System share sheet for pyxpo apps (react-native Share shape).
4
+
5
+ This is an optional [pyxpo](https://github.com/pyxpo/pyxpo) native module. Apps that do not
6
+ list it carry none of its code, permissions or dependencies.
7
+
8
+ ## Install
9
+
10
+ ```bash
11
+ pip install pyxpo-sharing
12
+ ```
13
+
14
+ Then link it into your app in `pyproject.toml`:
15
+
16
+ ```toml
17
+ [tool.pyxpo]
18
+ modules = ["sharing"]
19
+ ```
20
+
21
+ and rebuild (`pyxpo run ios`, `pyxpo build android`, ...). The build copies the module's Swift and Kotlin
22
+ sources into the native project and its Python package into the app.
23
+
24
+ ## Use
25
+
26
+ ```python
27
+ from pyxpo_sharing import Share
28
+
29
+ await Share.share({"url": path, "message": "Made with pyxpo"})
30
+ ```
31
+
32
+ Permissions and Info.plist keys: none (Android shares through a FileProvider declared in the module manifest).
33
+
34
+ ## What is in the package
35
+
36
+ - `pyxpo_sharing/__init__.py`: the Python API.
37
+ - `pyxpo_sharing/pyxpo-module.json`: autolink metadata (bridge name, Swift and Kotlin classes, Android namespace and dependencies, Info.plist keys).
38
+ - `pyxpo_sharing/ios/`: Swift sources compiled into the iOS app.
39
+ - `pyxpo_sharing/android/src/main/`: Kotlin sources and the manifest merged into the Android app.
@@ -0,0 +1,42 @@
1
+ [build-system]
2
+ requires = ["setuptools>=77"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "pyxpo-sharing"
7
+ dynamic = ["version"]
8
+ description = "System share sheet for pyxpo apps (react-native Share and expo-sharing shapes)."
9
+ readme = "README.md"
10
+ license = "MIT"
11
+ license-files = ["LICENSE"]
12
+ authors = [{ name = "Vishal Chaubey" }]
13
+ keywords = ["pyxpo", "pyxpo-module", "mobile", "android", "ios"]
14
+ classifiers = [
15
+ "Development Status :: 3 - Alpha",
16
+ "Intended Audience :: Developers",
17
+ "Programming Language :: Python :: 3",
18
+ "Topic :: Software Development :: User Interfaces",
19
+ ]
20
+ requires-python = ">=3.9"
21
+ dependencies = ["pyxpo>=0.1.0a1,<0.2"]
22
+
23
+ [project.urls]
24
+ Homepage = "https://github.com/pyxpo/pyxpo/tree/main/packages/sharing"
25
+ Issues = "https://github.com/pyxpo/pyxpo/issues"
26
+
27
+ # How `pyxpo build` finds this module: the entry point name is the module name apps list in
28
+ # `[tool.pyxpo] modules`, its value the import package holding pyxpo-module.json.
29
+ [project.entry-points."pyxpo.modules"]
30
+ sharing = "pyxpo_sharing"
31
+
32
+ [tool.setuptools]
33
+ packages = ["pyxpo_sharing"]
34
+
35
+ [tool.setuptools.dynamic]
36
+ version = { attr = "pyxpo_sharing.__version__" }
37
+
38
+ [tool.setuptools.package-data]
39
+ pyxpo_sharing = ["pyxpo-module.json", "py.typed", "ios/**/*", "android/**/*"]
40
+
41
+ [tool.setuptools.exclude-package-data]
42
+ "*" = ["__pycache__", "*.pyc", ".DS_Store"]
@@ -0,0 +1,68 @@
1
+ """System share sheet: react-native `Share` and expo-sharing shapes. Shares local files, links and an optional message."""
2
+ from __future__ import annotations
3
+
4
+ from typing import Any, Dict, List, Optional
5
+
6
+ from pyxpo.module_api import call, require_linked, snake_aliases
7
+
8
+ __version__ = "0.1.0a1"
9
+
10
+ _in_flight = False
11
+
12
+
13
+ def _is_link(s: str) -> bool:
14
+ return s.lower().startswith(("http://", "https://"))
15
+
16
+
17
+ async def _share(files: List[str], message: str, mime: str, title: str) -> Dict[str, str]:
18
+ """One share sheet at a time; a second call while one is open raises instead of stacking sheets."""
19
+ global _in_flight
20
+ if _in_flight:
21
+ raise RuntimeError("a share sheet is already open")
22
+ _in_flight = True
23
+ try:
24
+ res = await call("Share", "share", files, message, mime, title, reply=True)
25
+ finally:
26
+ _in_flight = False
27
+ return {"action": (res or {}).get("action", "dismissedAction")}
28
+
29
+
30
+ @snake_aliases
31
+ class Share:
32
+ @staticmethod
33
+ async def share(content: Dict[str, Any], options: Optional[Dict[str, Any]] = None) -> Dict[str, str]:
34
+ """Opens the system share sheet. `content`: `{"url": path_or_link}` or `{"urls": [...]}`, plus optional `message`.
35
+ Local paths are shared as files; http(s) links are appended to the message, the same on both OSes.
36
+ `options`: `{"dialogTitle": str}` (Android chooser title; iOS has none).
37
+ Returns `{"action": "sharedAction" | "dismissedAction"}` (Android always reports sharedAction, as react-native does).
38
+ Android shares files from the app's own cache and files folders."""
39
+ require_linked("Share", "sharing", package="pyxpo-sharing")
40
+ items = [str(u) for u in (content.get("urls") or ([content["url"]] if content.get("url") else []))]
41
+ files = [u for u in items if not _is_link(u)]
42
+ message = "\n".join([m for m in [content.get("message") or ""] + [u for u in items if _is_link(u)] if m])
43
+ if not files and not message:
44
+ raise ValueError("Share.share needs a url, urls or message")
45
+ return await _share(files, message, "", str((options or {}).get("dialogTitle") or ""))
46
+
47
+
48
+ @snake_aliases
49
+ class Sharing:
50
+ """expo-sharing shape."""
51
+
52
+ @staticmethod
53
+ async def isAvailableAsync() -> bool:
54
+ """True when the share sheet module is linked (both iOS and Android always have a share sheet)."""
55
+ try:
56
+ require_linked("Share", "sharing", package="pyxpo-sharing")
57
+ except Exception: # noqa: BLE001 - not linked means unavailable, not an error
58
+ return False
59
+ return True
60
+
61
+ @staticmethod
62
+ async def shareAsync(url: str, options: Optional[Dict[str, Any]] = None) -> None:
63
+ """Shares one local file. `options`: `mimeType` and `dialogTitle` (Android only; iOS derives both from the file)."""
64
+ require_linked("Share", "sharing", package="pyxpo-sharing")
65
+ if not url or _is_link(str(url)):
66
+ raise ValueError("Sharing.shareAsync needs a local file path; use Share.share for links")
67
+ o = options or {}
68
+ await _share([str(url)], "", str(o.get("mimeType") or ""), str(o.get("dialogTitle") or ""))
@@ -0,0 +1,10 @@
1
+ <manifest xmlns:android="http://schemas.android.com/apk/res/android">
2
+ <application>
3
+ <!-- Hands files from the app's cache and files folders to the share sheet without exposing file:// paths (no AndroidX needed). -->
4
+ <provider
5
+ android:name="dev.pyxpo.modules.sharing.PxShareFileProvider"
6
+ android:authorities="${applicationId}.pyxpo.share"
7
+ android:exported="false"
8
+ android:grantUriPermissions="true" />
9
+ </application>
10
+ </manifest>
@@ -0,0 +1,61 @@
1
+ package dev.pyxpo.modules.sharing
2
+
3
+ import android.content.ContentProvider
4
+ import android.content.ContentValues
5
+ import android.content.Context
6
+ import android.database.Cursor
7
+ import android.database.MatrixCursor
8
+ import android.net.Uri
9
+ import android.os.ParcelFileDescriptor
10
+ import android.provider.OpenableColumns
11
+ import android.webkit.MimeTypeMap
12
+ import java.io.File
13
+ import java.io.FileNotFoundException
14
+
15
+ /**
16
+ * Read-only provider for the share sheet. Serves only files inside the app's cache and files folders,
17
+ * addressed as content://<applicationId>.pyxpo.share/<absolute path>. Plain ContentProvider, so no AndroidX is needed.
18
+ */
19
+ class PxShareFileProvider : ContentProvider() {
20
+ override fun onCreate() = true
21
+
22
+ private fun resolve(uri: Uri): File {
23
+ val ctx = context ?: throw FileNotFoundException("no context")
24
+ val f = File("/" + uri.pathSegments.joinToString("/")).canonicalFile
25
+ if (!allowedRoots(ctx).any { f.path.startsWith(it.path + File.separator) } || !f.isFile) throw FileNotFoundException(uri.toString())
26
+ return f
27
+ }
28
+
29
+ override fun openFile(uri: Uri, mode: String): ParcelFileDescriptor {
30
+ if (mode != "r") throw FileNotFoundException("read-only")
31
+ return ParcelFileDescriptor.open(resolve(uri), ParcelFileDescriptor.MODE_READ_ONLY)
32
+ }
33
+
34
+ override fun getType(uri: Uri): String? = try {
35
+ MimeTypeMap.getSingleton().getMimeTypeFromExtension(resolve(uri).extension.lowercase()) ?: "application/octet-stream"
36
+ } catch (e: FileNotFoundException) { null }
37
+
38
+ override fun query(uri: Uri, projection: Array<String>?, selection: String?, selectionArgs: Array<String>?, sortOrder: String?): Cursor {
39
+ val f = resolve(uri)
40
+ val cols = projection ?: arrayOf(OpenableColumns.DISPLAY_NAME, OpenableColumns.SIZE)
41
+ val cur = MatrixCursor(cols)
42
+ cur.addRow(Array<Any?>(cols.size) { i -> when (cols[i]) { OpenableColumns.DISPLAY_NAME -> f.name; OpenableColumns.SIZE -> f.length(); else -> null } })
43
+ return cur
44
+ }
45
+
46
+ override fun insert(uri: Uri, values: ContentValues?): Uri? = throw UnsupportedOperationException("read-only")
47
+ override fun update(uri: Uri, values: ContentValues?, selection: String?, selectionArgs: Array<String>?): Int = throw UnsupportedOperationException("read-only")
48
+ override fun delete(uri: Uri, selection: String?, selectionArgs: Array<String>?): Int = throw UnsupportedOperationException("read-only")
49
+
50
+ companion object {
51
+ private fun allowedRoots(ctx: Context) = listOf(ctx.cacheDir.canonicalFile, ctx.filesDir.canonicalFile)
52
+
53
+ fun uriFor(ctx: Context, file: File): Uri {
54
+ val f = file.canonicalFile
55
+ if (!allowedRoots(ctx).any { f.path.startsWith(it.path + File.separator) }) {
56
+ throw IllegalArgumentException("only files in the app's cache or files folder can be shared")
57
+ }
58
+ return Uri.Builder().scheme("content").authority(ctx.packageName + ".pyxpo.share").path(f.path).build()
59
+ }
60
+ }
61
+ }
@@ -0,0 +1,59 @@
1
+ package dev.pyxpo.modules.sharing
2
+
3
+ import android.content.ClipData
4
+ import android.content.Intent
5
+ import android.net.Uri
6
+ import android.webkit.MimeTypeMap
7
+ import dev.pyxpo.moduleapi.PxModule
8
+ import dev.pyxpo.moduleapi.PxModuleContext
9
+ import dev.pyxpo.moduleapi.PxReply
10
+ import org.json.JSONArray
11
+ import java.io.File
12
+
13
+ /** System share sheet. Files must live in the app's cache or files folder. Like react-native, Android always reports sharedAction. */
14
+ class ShareModule : PxModule() {
15
+ override val name = "Share"
16
+
17
+ override fun call(ctx: PxModuleContext, method: String, args: JSONArray, reply: PxReply) {
18
+ if (method != "share") { reply(null, "unknown native call Share.$method"); return }
19
+ val paths = args.optJSONArray(0) ?: JSONArray()
20
+ val message = args.optString(1, "")
21
+ val mimeOverride = args.optString(2, "")
22
+ val title = args.optString(3, "")
23
+ val app = ctx.activity
24
+ val uris = ArrayList<Uri>()
25
+ val mimes = HashSet<String>()
26
+ try {
27
+ for (i in 0 until paths.length()) {
28
+ val raw = paths.optString(i)
29
+ val f = File(if (raw.startsWith("file://")) Uri.parse(raw).path ?: raw else raw)
30
+ if (!f.isFile) { reply(null, "file not found: ${f.name}"); return }
31
+ uris.add(PxShareFileProvider.uriFor(app, f))
32
+ mimes.add(MimeTypeMap.getSingleton().getMimeTypeFromExtension(f.extension.lowercase()) ?: "application/octet-stream")
33
+ }
34
+ } catch (e: IllegalArgumentException) {
35
+ reply(null, e.message ?: "file can not be shared"); return
36
+ }
37
+ val intent = Intent(if (uris.size > 1) Intent.ACTION_SEND_MULTIPLE else Intent.ACTION_SEND)
38
+ intent.type = when {
39
+ mimeOverride.isNotEmpty() -> mimeOverride
40
+ uris.isEmpty() -> "text/plain"
41
+ mimes.size == 1 -> mimes.first()
42
+ mimes.all { it.startsWith("image/") } -> "image/*"
43
+ else -> "*/*"
44
+ }
45
+ if (message.isNotEmpty()) intent.putExtra(Intent.EXTRA_TEXT, message)
46
+ if (uris.size == 1) intent.putExtra(Intent.EXTRA_STREAM, uris[0])
47
+ else if (uris.size > 1) intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris)
48
+ if (uris.isNotEmpty()) {
49
+ intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
50
+ intent.clipData = ClipData.newRawUri("", uris[0]).also { c -> for (u in uris.drop(1)) c.addItem(ClipData.Item(u)) }
51
+ }
52
+ try {
53
+ app.startActivity(Intent.createChooser(intent, title.ifEmpty { null }))
54
+ reply(mapOf("action" to "sharedAction"), null)
55
+ } catch (e: Throwable) {
56
+ reply(null, e.message ?: e.toString())
57
+ }
58
+ }
59
+ }
@@ -0,0 +1,33 @@
1
+ import UIKit
2
+
3
+ /// System share sheet (UIActivityViewController). Replies once the sheet closes.
4
+ final class ShareModule: PxModule {
5
+ static let moduleName = "Share"
6
+
7
+ required init() {}
8
+
9
+ func call(_ ctx: PxModuleContext, _ method: String, _ args: [Any], _ reply: @escaping PxReply) {
10
+ guard method == "share" else { reply(nil, "unknown native call Share.\(method)"); return }
11
+ let paths = (args.first as? [Any])?.compactMap { $0 as? String } ?? []
12
+ let message = (args.count > 1 ? args[1] as? String : nil) ?? ""
13
+ var items: [Any] = []
14
+ if !message.isEmpty { items.append(message) }
15
+ for p in paths {
16
+ let path = p.hasPrefix("file://") ? (URL(string: p)?.path ?? p) : p
17
+ guard FileManager.default.fileExists(atPath: path) else { reply(nil, "file not found: \((path as NSString).lastPathComponent)"); return }
18
+ items.append(URL(fileURLWithPath: path))
19
+ }
20
+ guard let top = ctx.presenter() else { reply(nil, "no view controller to present the share sheet"); return }
21
+ let vc = UIActivityViewController(activityItems: items, applicationActivities: nil)
22
+ vc.completionWithItemsHandler = { _, completed, _, err in
23
+ if let err = err { reply(nil, err.localizedDescription); return }
24
+ reply(["action": completed ? "sharedAction" : "dismissedAction"], nil)
25
+ }
26
+ if let pop = vc.popoverPresentationController {
27
+ pop.sourceView = top.view
28
+ pop.sourceRect = CGRect(x: top.view.bounds.midX, y: top.view.bounds.midY, width: 0, height: 0)
29
+ pop.permittedArrowDirections = []
30
+ }
31
+ top.present(vc, animated: true)
32
+ }
33
+ }
File without changes
@@ -0,0 +1,13 @@
1
+ {
2
+ "schemaVersion": 1,
3
+ "nativeContract": 1,
4
+ "name": "sharing",
5
+ "native": "Share",
6
+ "ios": { "classes": ["ShareModule"] },
7
+ "android": {
8
+ "namespace": "dev.pyxpo.modules.sharing",
9
+ "classes": ["dev.pyxpo.modules.sharing.ShareModule"],
10
+ "dependencies": [],
11
+ "minSdk": 24
12
+ }
13
+ }
@@ -0,0 +1,58 @@
1
+ Metadata-Version: 2.4
2
+ Name: pyxpo-sharing
3
+ Version: 0.1.0a1
4
+ Summary: System share sheet for pyxpo apps (react-native Share and expo-sharing shapes).
5
+ Author: Vishal Chaubey
6
+ License-Expression: MIT
7
+ Project-URL: Homepage, https://github.com/pyxpo/pyxpo/tree/main/packages/sharing
8
+ Project-URL: Issues, https://github.com/pyxpo/pyxpo/issues
9
+ Keywords: pyxpo,pyxpo-module,mobile,android,ios
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: Software Development :: User Interfaces
14
+ Requires-Python: >=3.9
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: pyxpo<0.2,>=0.1.0a1
18
+ Dynamic: license-file
19
+
20
+ # pyxpo-sharing
21
+
22
+ System share sheet for pyxpo apps (react-native Share shape).
23
+
24
+ This is an optional [pyxpo](https://github.com/pyxpo/pyxpo) native module. Apps that do not
25
+ list it carry none of its code, permissions or dependencies.
26
+
27
+ ## Install
28
+
29
+ ```bash
30
+ pip install pyxpo-sharing
31
+ ```
32
+
33
+ Then link it into your app in `pyproject.toml`:
34
+
35
+ ```toml
36
+ [tool.pyxpo]
37
+ modules = ["sharing"]
38
+ ```
39
+
40
+ and rebuild (`pyxpo run ios`, `pyxpo build android`, ...). The build copies the module's Swift and Kotlin
41
+ sources into the native project and its Python package into the app.
42
+
43
+ ## Use
44
+
45
+ ```python
46
+ from pyxpo_sharing import Share
47
+
48
+ await Share.share({"url": path, "message": "Made with pyxpo"})
49
+ ```
50
+
51
+ Permissions and Info.plist keys: none (Android shares through a FileProvider declared in the module manifest).
52
+
53
+ ## What is in the package
54
+
55
+ - `pyxpo_sharing/__init__.py`: the Python API.
56
+ - `pyxpo_sharing/pyxpo-module.json`: autolink metadata (bridge name, Swift and Kotlin classes, Android namespace and dependencies, Info.plist keys).
57
+ - `pyxpo_sharing/ios/`: Swift sources compiled into the iOS app.
58
+ - `pyxpo_sharing/android/src/main/`: Kotlin sources and the manifest merged into the Android app.
@@ -0,0 +1,16 @@
1
+ LICENSE
2
+ README.md
3
+ pyproject.toml
4
+ pyxpo_sharing/__init__.py
5
+ pyxpo_sharing/py.typed
6
+ pyxpo_sharing/pyxpo-module.json
7
+ pyxpo_sharing.egg-info/PKG-INFO
8
+ pyxpo_sharing.egg-info/SOURCES.txt
9
+ pyxpo_sharing.egg-info/dependency_links.txt
10
+ pyxpo_sharing.egg-info/entry_points.txt
11
+ pyxpo_sharing.egg-info/requires.txt
12
+ pyxpo_sharing.egg-info/top_level.txt
13
+ pyxpo_sharing/android/src/main/AndroidManifest.xml
14
+ pyxpo_sharing/android/src/main/java/dev/pyxpo/modules/sharing/PxShareFileProvider.kt
15
+ pyxpo_sharing/android/src/main/java/dev/pyxpo/modules/sharing/ShareModule.kt
16
+ pyxpo_sharing/ios/ShareModule.swift
@@ -0,0 +1,2 @@
1
+ [pyxpo.modules]
2
+ sharing = pyxpo_sharing
@@ -0,0 +1 @@
1
+ pyxpo<0.2,>=0.1.0a1
@@ -0,0 +1 @@
1
+ pyxpo_sharing
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+