-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
5 changed files
with
245 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
cache: pip | ||
matrix: | ||
fast_finish: true | ||
include: | ||
- name: Black | ||
env: RUN=black | ||
language: python | ||
python: 3.7 | ||
os: linux | ||
dist: bionic | ||
install: | ||
- pip install pycodestyle | ||
script: | ||
- pycodestyle iabwrapper/__init__.py | ||
after_failure: | ||
- sleep 10; | ||
- echo == End == | ||
deploy: | ||
skip_existing: true | ||
provider: pypi | ||
user: __token__ | ||
password: | ||
secure: Ns5qkp4xcg0FveWIOKpBmRRRf0qx/gb2JXPzNOl0hC30MtEi9arOv/3I6eowx8BgjyRIqoevCsxF+3LA6+aomoqYHcdMxo8rO5XB0/24h7zcZ4Al6XiINIXJX5Auu1AuPJhwBOuorI1jS7XwcvXjPXEEzcIIAGTuWTu6fHPWcaJOvaNcOHpHA932LI7TdrxM1VKPjCfISnBUmoYTkydDppq1ywhaPe66WS90dEaanYJr1i2ivAvFnCI3TIRSaWD0Kz4WiVoM7YYV+SRaBON4DCNoj9UEDYjWqr+DfcRRmwxrxnyxV3ljWYlo84osVYW6cjIz8A1ppwUBaQcoAG7P7ZmyC/wyqNLvo7Pqs5ggl2viAapiHepwPuriwGt+Kbm7PejUnAIQ/MGz86aY9ZNwDtVZLAJdJjwdfKt+PAtX9HJSzJ2/owqsULeDuNh/aoREMfZ6vuFo9XtK74h1oQU652M5g4tuK/QWmP0BzVzBQVr5JNpQUzCarHNZO2pfSJ8a1s8gOzLuuomh8WGxHdUNo0QSwqeSOLianXIK6f/Q+K+6Hnwi1JBZk7NXO/osPdXPPi6p+FgZR78kZKuOeqinJiC0dU/9SaOETLRJ3MCRJyZ1qqK+RjQu8QG9V5nmXiw44VTmpgIN4IU/yVtTVBJ4rAIHtLdGI/BsIKGgOfitdsw= | ||
distributions: sdist bdist_wheel | ||
on: | ||
tags: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
# android-iab-v3-kivy | ||
# IABwrapper | ||
Wrapper around anjlab's Android In-app Billing Version 3 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
from kivy.logger import Logger | ||
from kivy.utils import platform | ||
|
||
__version__ = "0.0.1" | ||
_log_message = ("IABwrapper:" | ||
+ f" {__version__}" | ||
+ f' (installed at "{__file__}")' | ||
) | ||
|
||
Logger.info(_log_message) | ||
|
||
if platform == "android": | ||
from main import PythonBillingProcessor | ||
|
||
else: | ||
Logger.error("IABwrapper: This module is only available on Android") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
from jnius import PythonJavaClass, autoclass, java_method | ||
from kivy.logger import Logger | ||
|
||
PythonActivity = autoclass("org.kivy.android.PythonActivity") | ||
|
||
BillingProcessor = autoclass("com.anjlab.android.iab.v3.BillingProcessor") | ||
PurchaseInfo = autoclass("com.anjlab.android.iab.v3.PurchaseInfo") | ||
SkuDetails = autoclass("com.anjlab.android.iab.v3.SkuDetails") | ||
|
||
context = PythonActivity.mActivity | ||
|
||
|
||
class PythonBillingHandler(PythonJavaClass): | ||
__javainterfaces__ = ["com/anjlab/android/iab/v3/BillingProcessor$IBillingHandler"] | ||
__javacontext__ = "app" | ||
|
||
def __init__( | ||
self, | ||
onProductPurchasedMethod, | ||
onBillingErrorMethod, | ||
onPurchaseHistoryRestoredMethod=None, | ||
onBillingInitializedMethod=None, | ||
): | ||
self.onBillingInitializedMethod = onBillingInitializedMethod | ||
self.onProductPurchasedMethod = onProductPurchasedMethod | ||
self.onBillingErrorMethod = onBillingErrorMethod | ||
self.onPurchaseHistoryRestoredMethod = onPurchaseHistoryRestoredMethod | ||
super(PythonBillingHandler, self).__init__() | ||
|
||
@java_method("()V") | ||
def onBillingInitialized(self): | ||
Logger.info("onBillingInitialized") | ||
if self.onBillingInitializedMethod: | ||
self.onBillingInitializedMethod() | ||
|
||
@java_method("(Ljava/lang/String;Lcom/anjlab/android/iab/v3/PurchaseInfo;)V") | ||
def onProductPurchased(self, productId, purchaseInfo): | ||
Logger.info("onProductPurchased: " + productId) | ||
self.onProductPurchasedMethod(productId, purchaseInfo) | ||
|
||
# Java method that takes an int and a Throwable | ||
@java_method("(Ljava/lang/Integer;Ljava/lang/Throwable;)V") | ||
def onBillingError(self, errorCode, error): | ||
Logger.info("onBillingError: " + str(errorCode)) | ||
self.onBillingErrorMethod(errorCode, error) | ||
|
||
@java_method("()V") | ||
def onPurchaseHistoryRestored(self): | ||
Logger.info("onPurchaseHistoryRestored") | ||
if self.onPurchaseHistoryRestoredMethod: | ||
self.onPurchaseHistoryRestoredMethod() | ||
|
||
|
||
class PythonIPurchasesResponseListener(PythonJavaClass): | ||
__javainterfaces__ = [ | ||
"com/anjlab/android/iab/v3/BillingProcessor$IPurchasesResponseListener" | ||
] | ||
__javacontext__ = "app" | ||
|
||
def __init__(self, onPurchasesSuccessMethod=None, onPurchasesErrorMethod=None): | ||
self.onPurchasesSuccessMethod = onPurchasesSuccessMethod | ||
self.onPurchasesErrorMethod = onPurchasesErrorMethod | ||
super(PythonIPurchasesResponseListener, self).__init__() | ||
|
||
@java_method("()V") | ||
def onPurchasesSuccess(self): | ||
Logger.info("onPurchasesSuccess") | ||
if self.onPurchasesSuccessMethod: | ||
self.onPurchasesSuccessMethod() | ||
|
||
@java_method("()V") | ||
def onPurchasesError(self): | ||
Logger.info("onPurchasesError") | ||
if self.onPurchasesErrorMethod: | ||
self.onPurchasesErrorMethod() | ||
|
||
|
||
class PythonISkuDetailsResponseListener(PythonJavaClass): | ||
__javainterfaces__ = [ | ||
"com/anjlab/android/iab/v3/BillingProcessor$ISkuDetailsResponseListener" | ||
] | ||
__javacontext__ = "app" | ||
|
||
def __init__(self, onSkuDetailsSuccessMethod=None, onSkuDetailsErrorMethod=None): | ||
self.onSkuDetailsSuccessMethod = onSkuDetailsSuccessMethod | ||
self.onSkuDetailsErrorMethod = onSkuDetailsErrorMethod | ||
super(PythonISkuDetailsResponseListener, self).__init__() | ||
|
||
@java_method("(Ljava/lang/Object;)V") | ||
def onSkuDetailsResponse(self, products): | ||
Logger.info("onSkuDetailsResponse") | ||
if self.onSkuDetailsSuccessMethod: | ||
self.onSkuDetailsSuccessMethod(products) | ||
|
||
@java_method("(Ljava/lang/String;)V") | ||
def onSkuDetailsError(self, error): | ||
Logger.info("onSkuDetailsError") | ||
if self.onSkuDetailsErrorMethod: | ||
self.onSkuDetailsErrorMethod(error) | ||
|
||
|
||
class PythonBillingProcessor(BillingProcessor): | ||
def __init__( | ||
self, | ||
license_key, | ||
onProductPurchasedMethod, | ||
onBillingErrorMethod, | ||
onPurchaseHistoryRestoredMethod=None, | ||
onBillingInitializedMethod=None, | ||
): | ||
self.billing_handler = PythonBillingHandler( | ||
onProductPurchasedMethod, | ||
onBillingErrorMethod, | ||
onPurchaseHistoryRestoredMethod, | ||
onBillingInitializedMethod, | ||
) | ||
|
||
super().__init__(context, license_key, self.billing_handler) | ||
self.initialize() | ||
|
||
def purchase(self, product_id): | ||
super().purchase(context, product_id) | ||
|
||
def consumePurchaseAsync( | ||
self, product_id, success_listener=None, error_listener=None | ||
): | ||
purchases_response_listener = PythonIPurchasesResponseListener( | ||
success_listener, error_listener | ||
) | ||
super().consumePurchaseAsync(product_id, purchases_response_listener) | ||
|
||
def getPurchaseListingDetailsAsync( | ||
self, product_id, success_listener=None, error_listener=None | ||
): | ||
sku_details_listener = PythonISkuDetailsResponseListener( | ||
success_listener, error_listener | ||
) | ||
super().getPurchaseListingDetailsAsync(product_id, sku_details_listener) | ||
|
||
def subscribe(self, subscription_id): | ||
super().subscribe(context, subscription_id) | ||
|
||
def loadOwnedPurchasesFromGoogleAsync( | ||
self, success_listener=None, error_listener=None | ||
): | ||
purchases_response_listener = PythonIPurchasesResponseListener( | ||
success_listener, error_listener | ||
) | ||
super().loadOwnedPurchasesFromGoogleAsync(purchases_response_listener) | ||
|
||
def getSubscriptionListingDetailsAsync( | ||
self, subscription_id, success_listener=None, error_listener=None | ||
): | ||
sku_details_listener = PythonISkuDetailsResponseListener( | ||
success_listener, error_listener | ||
) | ||
super().getSubscriptionListingDetailsAsync( | ||
subscription_id, sku_details_listener | ||
) | ||
|
||
def __del__(self): | ||
self.release() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
from setuptools import setup | ||
import os, re | ||
|
||
with open("README.md", "r") as fh: | ||
long_description = fh.read() | ||
|
||
|
||
def get_version() -> str: | ||
"""Get __version__ from __init__.py file.""" | ||
version_file = os.path.join(os.path.dirname(__file__), "iabwrapper", "__init__.py") | ||
version_file_data = open(version_file, "rt", encoding="utf-8").read() | ||
version_regex = r"(?<=^__version__ = ['\"])[^'\"]+(?=['\"]$)" | ||
try: | ||
version = re.findall(version_regex, version_file_data, re.M)[0] | ||
return version | ||
except IndexError: | ||
raise ValueError(f"Unable to find version string in {version_file}.") | ||
|
||
|
||
setup( | ||
name="IABwrapper", | ||
version=get_version(), | ||
packages=["iabwrapper"], | ||
package_data={"iabwrapper": ["*.py"],}, | ||
# metadata to display on PyPI | ||
author="Shashi Ranjan", | ||
author_email="shashiranjankv@gmail.com", | ||
description="Wrapper around anjlab's Android In-app Billing Version 3 to be used in Kivy apps", | ||
long_description=long_description, | ||
long_description_content_type="text/markdown", | ||
keywords="iab playstore billing android kivy-application kivy python", | ||
url="https://github.com/shashi278/android-iab-v3-kivy", | ||
classifiers=[ | ||
"Programming Language :: Python :: 3", | ||
"License :: OSI Approved :: MIT License", | ||
"Operating System :: Android", | ||
], | ||
install_requires=["kivy"], | ||
python_requires=">=3.6", | ||
) |