diff --git a/python3_requirements.txt b/python3_requirements.txt index bf9f860c..2f963acf 100644 --- a/python3_requirements.txt +++ b/python3_requirements.txt @@ -2,19 +2,29 @@ astroid==2.3.3 certifi==2019.9.11 chardet==3.0.4 docutils==0.15.2 +flake8==3.8.2 idna==2.8 +importlib-metadata==1.6.0 isort==4.3.21 Kivy==1.11.1 Kivy-Garden==0.1.4 --e git+https://github.com/surbhicis/KivyMD-1#egg=kivymd +kivy-garden.qrcode==2019.914 +kivymd==0.104.0 lazy-object-proxy==1.4.3 mccabe==0.6.1 +numpy==1.18.4 +opencv-python==4.2.0.34 Pillow==6.1.0 +pycodestyle==2.6.0 pydenticon==0.3.1 +pyflakes==2.2.0 Pygments==2.4.2 pylint==2.4.4 +pyzbar==0.1.8 qrcode==6.1 requests==2.22.0 six==1.12.0 typed-ast==1.4.0 urllib3==1.25.6 +wrapt==1.11.2 +zipp==3.1.0 \ No newline at end of file diff --git a/src/bitmessagekivy/kv/composer.kv b/src/bitmessagekivy/kv/composer.kv index 180412ab..e6f2f1ef 100644 --- a/src/bitmessagekivy/kv/composer.kv +++ b/src/bitmessagekivy/kv/composer.kv @@ -54,7 +54,8 @@ MDIconButton: icon: 'qrcode-scan' pos_hint: {'center_x': 0, 'center_y': .8} - on_press: root.qrScanner() + on_release: + app.root.ids.scr_mngr.current = 'scanscreen' MyMDTextField: id: subject diff --git a/src/bitmessagekivy/kv/login.kv b/src/bitmessagekivy/kv/login.kv index 2548a758..22e86689 100644 --- a/src/bitmessagekivy/kv/login.kv +++ b/src/bitmessagekivy/kv/login.kv @@ -1,120 +1,303 @@ +#:import SlideTransition kivy.uix.screenmanager.SlideTransition : - name: 'login' - ScrollView: - do_scroll_x: False + name:"login" + BoxLayout: + orientation: "vertical" + + #buttons-area-outer BoxLayout: - orientation: 'vertical' - size_hint_y: None - height: dp(450) + self.minimum_height - padding: dp(10) - BoxLayout: - MDLabel: - font_style: 'Subtitle2' - theme_text_color: 'Primary' - text: root.log_text1 - halign: 'left' - color:app.theme_cls.primary_dark - BoxLayout: - MDLabel: - font_style: 'Subtitle2' - theme_text_color: 'Primary' - text: root.log_text2 - halign: 'left' - color:app.theme_cls.primary_dark - Widget: - size_hint: (None, None) - height: dp(10) - MDCheckbox: - id: grp_chkbox_1 - group: 'test' - size_hint: None, None - size: dp(48), dp(48) - pos_hint: {'center_x': .5, 'center_y': .5} - active: True - allow_no_selection: False - MDLabel: - font_style: 'Body2' - theme_text_color: 'Primary' - text: "use a random number generator to make an address" - halign: 'center' - size_hint_y: None - height: self.texture_size[1] + dp(4) - color: [0.941, 0, 0,1] - MDCheckbox: - id: grp_chkbox_1 - group: 'test' - size_hint: None, None - size: dp(48), dp(48) - pos_hint: {'center_x': .5, 'center_y': .5} - allow_no_selection: False - MDLabel: - font_style: 'Body2' - theme_text_color: 'Primary' - text: "use a pseudo number generator to make an address" - halign: 'center' - size_hint_y: None - color: [0.941, 0, 0,1] - height: self.texture_size[1] + dp(4) - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: (.2, None) - # height: dp(40) - on_press: app.root.ids.scr_mngr.current = 'random' - on_press: app.root.ids.sc7.reset_address_label() - MDLabel: - font_style: 'H6' - text: 'proceed' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' + size_hint_y: .53 + canvas: + Color: + rgba: 1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + + ScreenManager: + id: check_screenmgr + Screen: + name: "check_screen" + BoxLayout: + orientation: "vertical" + padding: 0, dp(5), 0, dp(5) + spacing: dp(5) + + #label area + AnchorLayout: + size_hint_y: None + height: dp(50) + MDLabel: + text: "Select method to make an address:" + bold: True + halign: "center" + theme_text_color: "Custom" + text_color: .4,.4,.4,1 + + #upper-checkbor-area + AnchorLayout: + size_hint_y: None + height: dp(40) + BoxLayout: + size_hint_x: None + width: self.minimum_width + + #check-container + AnchorLayout: + size_hint_x: None + width: dp(40) + Check: + active: True + + #text-container + AnchorLayout: + size_hint_x: None + width: dp(200) + MDLabel: + text: "Random Number Generator" + + AnchorLayout: + size_hint_y: None + height: dp(40) + BoxLayout: + size_hint_x: None + width: self.minimum_width + + #check-container + AnchorLayout: + size_hint_x: None + width: dp(40) + Check: + + #text-container + AnchorLayout: + size_hint_x: None + width: dp(200) + MDLabel: + text: "Pseudo Number Generator" + AnchorLayout: + MDFillRoundFlatIconButton: + icon: "chevron-double-right" + text: "Proceed Next" + on_release: + app.root.ids.scr_mngr.current = 'random' + on_press: + app.root.ids.sc7.reset_address_label(app) + + + Screen: + name: "label_screen" + BoxLayout: + orientation: "vertical" + padding: 0, dp(5), 0, dp(5) + spacing: dp(5) + + #label area + AnchorLayout: + size_hint_y: None + height: dp(50) + MDLabel: + text: "Enter a label to generate address for:" + bold: True + halign: "center" + theme_text_color: "Custom" + text_color: .4,.4,.4,1 + + AnchorLayout: + size_hint_y: None + height: dp(40) + MDTextField: + hint_text: "Label" + required: True + size_hint_x: None + width: dp(190) + + AnchorLayout: + MDFillRoundFlatIconButton: + icon: "chevron-double-right" + text: "Proceed Next" + + Widget: + + + + #info-area-outer + BoxLayout: + size_hint_y: .47 + padding: dp(7) + InfoLayout: + orientation:"vertical" + padding: 0, dp(5), 0, dp(5) + canvas: + Color: + rgba:1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + Color: + rgba: app.theme_cls.primary_color + Line: + rounded_rectangle: (self.pos[0]+4, self.pos[1]+4, self.width-8,self.height-8, 10, 10, 10, 10, 50) + width: dp(1) + ScreenManager: + id: info_screenmgr + + Screen: + name: "info1" + ScrollView: + bar_width:0 + do_scroll_x: False + + BoxLayout: + orientation: "vertical" + size_hint_y: None + height: self.minimum_height + + #note area + ContentHead: + section_name: "NOTE:" + ContentBody: + section_text: ("You may generate addresses by using either random numbers or by using a pass-phrase.If you use a pass-phrase, the address is called a deterministic address. The Random Number option is selected by default but deterministic addresses may have several pros and cons.") + + + #pros area + ContentHead: + section_name: "PROS:" + ContentBody: + section_text: ("You can re-create your addresses on any computer from memory you need-not-to worry about backing up your keys.dat file as long as you can remember your pass-phrase.") + + #cons area + ContentHead: + section_name: "CONS:" + ContentBody: + section_text: ("You must remember (or write down) your address version number and the stream number along with your pass-phrase.If you choose a weak pass-phrase and someone on the internet can brute-force it, they can read your messages and send messages as you.") : - name: 'random' - ScrollView: - id: add_random_bx + name:"random" + BoxLayout: + orientation: "vertical" + id:add_random_bx + #buttons-area-outer + BoxLayout: + size_hint_y: .53 + canvas: + Color: + rgba: 1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + + ScreenManager: + id: check_screenmgr + Screen: + name: "label_screen" + BoxLayout: + orientation: "vertical" + padding: 0, dp(5), 0, dp(5) + spacing: dp(5) -: - orientation: 'vertical' + #label area + AnchorLayout: + size_hint_y: None + height: dp(50) + MDLabel: + text: "Enter a label to generate address for:" + bold: True + halign: "center" + theme_text_color: "Custom" + text_color: .4,.4,.4,1 + + AnchorLayout: + size_hint_y: None + height: dp(40) + MDTextField: + id:lab + hint_text: "Label" + required: True + size_hint_x: None + width: dp(190) + helper_text_mode: "on_error" + helper_text: "Please enter your label name" + + AnchorLayout: + MDFillRoundFlatIconButton: + icon: "chevron-double-right" + text: "Proceed Next" + on_release: app.root.ids.sc7.generateaddress(app) + + Widget: + + + + #info-area-outer + BoxLayout: + size_hint_y: .47 + padding: dp(7) + InfoLayout: + orientation:"vertical" + padding: 0, dp(5), 0, dp(5) + canvas: + Color: + rgba:1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + Color: + rgba: app.theme_cls.primary_color + Line: + rounded_rectangle: (self.pos[0]+4, self.pos[1]+4, self.width-8,self.height-8, 10, 10, 10, 10, 50) + width: dp(1) + ScreenManager: + id: info_screenmgr + + Screen: + name: "info2" + ScrollView: + bar_width:0 + do_scroll_x: False + + BoxLayout: + orientation: "vertical" + size_hint_y: None + height: self.minimum_height + + #note area + ContentHead: + section_name: "NOTE:" + ContentBody: + section_text: ("Here you may generate as many addresses as you like..Indeed creating and abandoning addresses is not encouraged.") + +: + group: 'group' + size_hint: None, None + size: dp(48), dp(48) + +: + section_name: "" + orientation: "vertical" + size_hint_y: None + height: dp(50) + padding: dp(20), 0, 0, 0 + Widget: + size_hint_y: None + height: dp(25) + MDLabel: + theme_text_color: "Custom" + text_color: .1,.1,.1,.9 + text: root.section_name + bold: True + font_style: "Button" + +: + section_text: "" size_hint_y: None height: self.minimum_height - padding: dp(20) - spacing: 100 - MDLabel: - font_style: 'Subtitle2' - theme_text_color: 'Primary' - text: "Random Addresses" - halign: 'center' - color:app.theme_cls.primary_dark + padding: dp(50), 0, dp(10), 0 MDLabel: - font_style: 'Subtitle2' - theme_text_color: 'Primary' - text: "Here you may generate as many addresses as you like, Indeed creating and abandoning addresses is encouraged" - halign: 'left' - color:app.theme_cls.primary_dark - - MDTextField: - id: label - multiline: False - hint_text: "Label" - required: True - helper_text_mode: "on_error" - on_text: app.root.ids.sc7.add_validation(self) - canvas.before: - Color: - rgba: (0,0,0,1) - - BoxLayout: - AnchorLayout: - MDRaisedButton: - size_hint: (.2, None) - # height: dp(40) - on_release: app.root.ids.sc7.generateaddress(app) - opposite_colors: True - MDLabel: - font_style: 'H6' - text: 'next' - font_size: '13sp' - color: (1,1,1,1) - halign: 'center' + size_hint_y: None + height: self.texture_size[1]+dp(10) + theme_text_color: "Custom" + text_color: 0.3,0.3,0.3,1 + font_style: "Body1" + text: root.section_text diff --git a/src/bitmessagekivy/kv/payment.kv b/src/bitmessagekivy/kv/payment.kv index 4e41cd02..847ee698 100644 --- a/src/bitmessagekivy/kv/payment.kv +++ b/src/bitmessagekivy/kv/payment.kv @@ -1,148 +1,253 @@ +#:import get_color_from_hex kivy.utils.get_color_from_hex + : - name: 'payment' - ScrollView: - do_scroll_x: False + name: "payment" + BoxLayout: + ScrollView: + bar_width:0 + do_scroll_x: False + #scroll_y:0 + + BoxLayout: + spacing: dp(8) + padding: dp(5) + size_hint_y: None + height: self.minimum_height + orientation: "vertical" + + ProductCategoryLayout: + category_text: "Monthly-Subscriptions" + + ProductLayout: + heading_text: "Gas (Play Billing Codelab)" + price_text: "$0.99" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Buy gasoline to ride!" + product_id: "SKUGASBILLING" + + ProductLayout: + heading_text: "Upgrade your car (Play Billing Codelab)" + price_text: "$1.49" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Buy a premium outfit for your car!" + product_id: "SKUUPGRADECAR" + + ProductLayout: + heading_text: "Month in gold status (Play Billing Codelab)" + price_text: "$0.99" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Enjoy a gold status for a month!" + product_id: "SKUMONTHLYGOLD" + + ProductCategoryLayout: + category_text: "One-time payment" + + ProductLayout: + heading_text: "Gas (Play Billing Codelab)" + price_text: "$0.99" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Buy gasoline to ride!" + product_id: "SKUONETIMEGAS" + + ProductCategoryLayout: + category_text: "Annual-Subscriptions" + + ProductLayout: + heading_text: "Gas (Play Billing Codelab)" + price_text: "$0.99" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Buy gasoline to ride!" + product_id: "SKUANNUALGAS" + + ProductLayout: + heading_text: "Year in gold status (Play Billing Codelab)" + price_text: "$10.99" + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buynew1.png" + description_text: "Enjoy a gold status for a year!" + product_id: "SKUANNUALGOLD" + +: + size_hint_y: None + height: self.minimum_height + category_text:"" + + orientation: "vertical" + spacing: 2 + + #category area + Category: + text_: root.category_text + +: + canvas: + Color: + rgba: 1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + text_: "" + size_hint_y: None + height: dp(30) + Widget: + size_hint_x: None + width: dp(20) + MDLabel: + text: root.text_ + font_size: sp(15) + +: + heading_text: "" + price_text: "" + source: "" + description_text: "" + + product_id: "" + + canvas: + Color: + rgba: 1,1,1,1 + Rectangle: + pos: self.pos + size: self.size + + size_hint_y: None + height: dp(200) + orientation: "vertical" + + #heading area + BoxLayout: + size_hint_y: 0.3 + + #text heading BoxLayout: - orientation: 'vertical' - padding: [dp(app.window_size[0]/16 if app.window_size[0] <= 720 else app.window_size[0]/6 if app.window_size[0] <= 800 else app.window_size[0]/18), dp(10)] - spacing: 12 - size_hint_y: None - height: self.minimum_height + dp(app.window_size[1]) if app.window_size[1] > app.window_size[0] else dp(app.window_size[0]) + Widget: + size_hint_x: None + width: dp(20) + MDLabel: + text: root.heading_text + bold: True + + #price text + BoxLayout: + size_hint_x:.3 + MDLabel: + text: root.price_text + bold: True + halign: "right" + theme_text_color: "Custom" + text_color: 0,0,1,1 + Widget: + size_hint_x: None + width: dp(20) + + #details area + BoxLayout: + size_hint_y: 0.3 + Widget: + size_hint_x: None + width: dp(20) + + #image area + AnchorLayout: + size_hint_x: None + width: self.height BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: + canvas: Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout - pos: self.pos + rgba: 1,1,1,1 + Ellipse: size: self.size - MDLabel: - size_hint_y: None - font_style: 'H5' - theme_text_color: 'Primary' - text: 'Platinum' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subtitle1' - theme_text_color: 'Primary' - text: 'We provide subscriptions for proof of work calculation for first month. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - id: free_pak - font_style: 'H5' - theme_text_color: 'Primary' - text: '€ 50.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size: app.window_size[0] - 2*self.parent.parent.padding[0] - dp(10) , 1 - height: dp(40) - on_press: root.get_free_credits(self) - MDLabel: - font_style: 'H6' - text: 'Get Free Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' - BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: - Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout pos: self.pos - size: self.size - MDLabel: - size_hint_y: None - font_style: 'H5' - theme_text_color: 'Primary' - text: 'Silver' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subtitle1' - theme_text_color: 'Primary' - text: 'We provide for proof of work calculation for six month. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - id: py2 - font_style: 'H5' - theme_text_color: 'Primary' - text: '€ 100.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size: app.window_size[0] - 2*self.parent.parent.padding[0] - dp(10) , 1 - height: dp(40) - on_press: root.create_hidden_payment_address(self) - MDLabel: - font_style: 'H6' - text: 'Buy 100 Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' - BoxLayout: - orientation: 'vertical' - padding: dp(5) - canvas.before: - Color: - rgba: app.theme_cls.primary_dark - Rectangle: - # self here refers to the widget i.e FloatLayout - pos: self.pos - size: self.size - MDLabel: - size_hint_y: None - font_style: 'H5' - theme_text_color: 'Primary' - text: 'Gold' - halign: 'center' - color: 1,1,1,1 - MDLabel: - font_style: 'Subtitle1' - theme_text_color: 'Primary' - text: 'We provide for proof of work calculation for 1years. ' - halign: 'center' - color: 1,1,1,1 - MDLabel: - id: py3 - font_style: 'H5' - theme_text_color: 'Primary' - text: '€ 500.0' - halign: 'center' - color: 1,1,1,1 - MDRaisedButton: - canvas: - Color: - rgb: (0.93, 0.93, 0.93) - Rectangle: - pos: self.pos - size: self.size - size: app.window_size[0] - 2*self.parent.parent.padding[0] - dp(10) , 1 - height: dp(40) - on_press: root.create_hidden_payment_address(self) - MDLabel: - font_style: 'H6' - text: 'Buy 500 Credits' - font_size: '13sp' - color: (0,0,0,1) - halign: 'center' \ No newline at end of file + source: root.source + Widget: + size_hint_x: None + width: dp(10) + + #description text + BoxLayout: + #size_hint_x: 1 + MDLabel: + text: root.description_text + font_size: sp(15) + + #Button Area + BoxLayout: + size_hint_y: 0.4 + Widget: + + AnchorLayout: + anchor_x: "right" + MDRaisedButton: + elevation_normal: 5 + text: "BUY" + on_release: + #print(app) + app.open_payment_layout(root.product_id) + + Widget: + size_hint_x: None + width: dp(20) + +: + on_release: app.initiate_purchase(self.method_name) + recent: False + source: "" + method_name: "" + right_label_text: "Recent" if self.recent else "" + + ImageLeftWidget: + source: root.source + + RightLabel: + text: root.right_label_text + theme_text_color: "Custom" + text_color: 0,0,0,.4 + font_size: sp(12) + +: + orientation: "vertical" + size_hint_y: None + height: "200dp" + + BoxLayout: + size_hint_y: None + height: dp(40) + + Widget: + size_hint_x: None + width: dp(20) + MDLabel: + text: "Select Payment Method" + font_size: sp(14) + bold: True + theme_text_color: "Custom" + text_color: 0,0,0,.5 + + + ScrollView: + + GridLayout: + cols: 1 + size_hint_y:None + height:self.minimum_height + + ListItemWithLabel: + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/gplay.png" + text: "Google Play" + method_name: "gplay" + recent: True + + ListItemWithLabel: + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/btc.png" + text: "BTC" + method_name: "btc" + + ListItemWithLabel: + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/paypal.png" + text: "Paypal" + method_name: "som" + + ListItemWithLabel: + source: "/home/surbhi/Downloads/peter3/PyBitmessage/src/images/buy.png" + text: "One more method" + method_name: "omm" \ No newline at end of file diff --git a/src/bitmessagekivy/kv/popup.kv b/src/bitmessagekivy/kv/popup.kv index 26ff017c..e8642f8d 100644 --- a/src/bitmessagekivy/kv/popup.kv +++ b/src/bitmessagekivy/kv/popup.kv @@ -79,6 +79,9 @@ MDRaisedButton: size_hint: 2, None height: dp(40) + on_press: root.dismiss() + on_release: + app.root.ids.scr_mngr.current = 'scanscreen' MDLabel: font_style: 'H6' text: 'Scan QR code' diff --git a/src/bitmessagekivy/main.kv b/src/bitmessagekivy/main.kv index dba77d71..f0f2bf79 100644 --- a/src/bitmessagekivy/main.kv +++ b/src/bitmessagekivy/main.kv @@ -16,6 +16,7 @@ #:import MDScrollViewRefreshLayout kivymd.uix.refreshlayout.MDScrollViewRefreshLayout #:import MDSpinner kivymd.uix.spinner.MDSpinner #:import MDTabsBase kivymd.uix.tab.MDTabsBase +#:import ZBarSymbol pyzbar.pyzbar.ZBarSymbol #:set color_button (0.784, 0.443, 0.216, 1) # brown @@ -180,8 +181,8 @@ on_release: app.root.ids.scr_mngr.current = 'set' on_release: root.parent.set_state() NavigationItem: - text: 'Payment' - icon: 'bell' + text: 'Purchase' + icon: 'shopping' divider: None on_release: app.root.ids.scr_mngr.current = 'payment' on_release: root.parent.set_state() @@ -273,6 +274,8 @@ NavigationLayout: id:sc21 ChatList: id:sc22 + ScanScreen: + id:sc23 MDNavigationDrawer: id: nav_drawer @@ -342,3 +345,9 @@ NavigationLayout: color: 0,0,0,1 color: 0,0,0,1 + +: + name:'scanscreen' + + + \ No newline at end of file diff --git a/src/bitmessagekivy/mpybit.py b/src/bitmessagekivy/mpybit.py index a1e22ae7..b7b4b0ee 100644 --- a/src/bitmessagekivy/mpybit.py +++ b/src/bitmessagekivy/mpybit.py @@ -4,6 +4,71 @@ Bitmessage android(mobile) interface # pylint: disable=too-many-lines,import-error,no-name-in-module,unused-argument # pylint: disable=too-many-ancestors,too-many-locals,useless-super-delegation # pylint: disable=protected-access + + +from sys import platform as _sys_platform +from os import environ + +''' +We need to check platform and set environ for KIVY_CAMERA, if requires, before importing kivy. + +We cannot use sys.platform directly because it returns 'linux' on android devices as well. +We cannot use kivy.util.platform beacuse it imports kivy beforehand and thus setting environ +after that doesn't make any sense. + +So we needed to copy the `_get_platform` function from kivy.utils +''' + +def _get_platform(): + # On Android sys.platform returns 'linux2', so prefer to check the + # existence of environ variables set during Python initialization + kivy_build = environ.get('KIVY_BUILD', '') + if kivy_build in {'android', 'ios'}: + return kivy_build + elif 'P4A_BOOTSTRAP' in environ: + return 'android' + elif 'ANDROID_ARGUMENT' in environ: + # We used to use this method to detect android platform, + # leaving it here to be backwards compatible with `pydroid3` + # and similar tools outside kivy's ecosystem + return 'android' + elif _sys_platform in ('win32', 'cygwin'): + return 'win' + elif _sys_platform == 'darwin': + return 'macosx' + elif _sys_platform.startswith('linux'): + return 'linux' + elif _sys_platform.startswith('freebsd'): + return 'linux' + return 'unknown' + +platform= _get_platform() + +if platform=='android': + from jnius import autoclass, cast + from android.runnable import run_on_ui_thread + from android import python_act as PythonActivity + + Toast= autoclass('android.widget.Toast') + String = autoclass('java.lang.String') + CharSequence= autoclass('java.lang.CharSequence') + context= PythonActivity.mActivity + + @run_on_ui_thread + def show_toast(text, length): + t= Toast.makeText(context, text, length) + t.show() + +else: + ''' + After tweaking a little bit with opencv camera, it's possible to make camera + go on and off as required while the app is still running. + + Other camera provider such as `gi` has some issue upon closing the camera. + by setting KIVY_CAMERA environment variable before importing kivy, we are forcing it to use opencv camera provider. + ''' + environ['KIVY_CAMERA']='opencv' + import os import time from bitmessagekivy import identiconGeneration @@ -71,6 +136,11 @@ import state from addresses import decodeAddress from kivy.uix.modalview import ModalView from datetime import datetime +from kivymd.uix.behaviors.elevation import RectangularElevationBehavior +from kivymd.uix.bottomsheet import MDCustomBottomSheet +from kivy.effects.dampedscroll import DampedScrollEffect +from kivy_garden.zbarcam import ZBarCam +from pyzbar.pyzbar import ZBarSymbol if platform != 'android': from kivy.config import Config @@ -832,6 +902,57 @@ class DropDownWidget(BoxLayout): """This method is used for scanning Qr code""" pass +class ScanScreen(Screen): + def on_pre_enter(self): + ''' + on_pre_enter works little better on android + It affects screen transition on linux + ''' + if not self.children: + tmp= Builder.load_file(os.path.join(os.path.dirname(__file__), "kv/{}.kv").format('scanner')) + self.add_widget(tmp) + if platform=='android': + Clock.schedule_once(self.start_camera, 0) + + def on_enter(self): + ''' + on_enter works better on linux + It creates a black screen on android until camera gets loaded + ''' + #print(self.children) + if platform!='android': + #pass + Clock.schedule_once(self.start_camera, 0) + + def on_leave(self): + #pass + + Clock.schedule_once(self.stop_camera, 0) + + def start_camera(self, *args): + self.xcam= self.children[0].ids.zbarcam.ids.xcamera + #pass + #self.xxx= self.children[0].ids.zbarcam.ids.xcamera + #print(self.cam._device.isOpened()) + if platform=='android': + self.xcam.play= True + + else: + Clock.schedule_once(self.open_cam, 0) + + + def stop_camera(self, *args): + #print(self.children[0].ids.zbarcam.ids.xcamera.play) + self.xcam.play= False + #self.xcam._camera.stop() + #self.children[0].ids.zbarcam.stop() + if platform != 'android': + self.xcam._camera._device.release() + + def open_cam(self, *args): + if not self.xcam._camera._device.isOpened(): + self.xcam._camera._device.open(self.xcam._camera._index) + self.xcam.play= True class MyTextInput(TextInput): """Takes the text input in the field""" @@ -902,6 +1023,23 @@ class Payment(Screen): payloadLengthExtraBytes)) toast('hidden payment address Creating for buying subscription....') +class Category(BoxLayout, RectangularElevationBehavior): + elevation_normal= .01 + +class ProductLayout(BoxLayout, RectangularElevationBehavior): + elevation_normal= .01 + +class PaymentMethodLayout(BoxLayout): + pass + +class ListItemWithLabel(OneLineAvatarIconListItem): + pass + +class RightLabel(IRightBodyTouch, MDLabel): + pass + +class HomeScreen(Screen): + pass class Credits(Screen): """Credits Method""" @@ -987,9 +1125,10 @@ class Random(Screen): def generateaddress(self, navApp): """Method for Address Generator""" - entered_label = str(self.ids.add_random_bx.children[0].ids.label.text).strip() + entered_label = str(self.ids.lab.text).strip() if not entered_label: - self.ids.add_random_bx.children[0].ids.label.focus = True + self.ids.lab.focus = True + # self.ids.add_random_bx.children[0].ids.label.focus = True # self.ids.label.error = True # self.ids.label.helper_text = 'This field is required' streamNumberForAddress = 1 @@ -1045,7 +1184,7 @@ class Random(Screen): instance.error = False instance.helper_text = 'This field is required' - def reset_address_label(self): + def reset_address_label(self, n): """Resetting address labels""" if not self.ids.add_random_bx.children: self.ids.add_random_bx.add_widget(RandomBoxlayout()) @@ -2081,9 +2220,26 @@ class NavigateApp(MDApp): def reset_login_screen(self): """This method is used for clearing random screen""" - if self.root.ids.sc7.ids.add_random_bx.children: - self.root.ids.sc7.ids.add_random_bx.clear_widgets() + # if self.root.ids.sc7.ids.add_random_bx.children: + # self.root.ids.sc7.ids.add_random_bx.clear_widgets() + def open_payment_layout(self, sku): + pml= PaymentMethodLayout() + self.product_id= sku + self.custom_sheet= MDCustomBottomSheet(screen= pml) + self.custom_sheet.open() + + def initiate_purchase(self, method_name): + #self.custom_sheet.dismiss() + print("Purchasing {} through {}".format(self.product_id, method_name)) + + def _after_scan(self, text): + if platform=='android': + text= cast(CharSequence, String(text)) + show_toast(text,Toast.LENGTH_SHORT) + else: + self.root.ids.sc3.children[1].ids.txt_input.text = text + self.root.ids.scr_mngr.current = 'create' class GrashofPopup(Popup): """Moule for save contacts and error messages""" @@ -2199,6 +2355,8 @@ class GrashofPopup(Popup): text = "Some data encoded in the address is malformed." return text +class InfoLayout(BoxLayout, RectangularElevationBehavior): + pass class AvatarSampleWidget(ILeftBody, Image): """Avatar Sample Widget""" @@ -2515,7 +2673,7 @@ class ShowQRCode(Screen): """Method used for showing QR Code""" self.ids.qr.clear_widgets() state.kivyapp.set_toolbar_for_QrCode() - from kivy.garden.qrcode import QRCodeWidget + from kivy_garden.qrcode import QRCodeWidget try: address = self.manager.get_parent_window().children[0].address except Exception: diff --git a/src/buildozer.spec b/src/buildozer.spec index 3c4c0180..df464e77 100644 --- a/src/buildozer.spec +++ b/src/buildozer.spec @@ -1,19 +1,19 @@ [app] # (str) Title of your application -title = py3 +title = tor # (str) Package name -package.name = py3 +package.name = tor # (str) Package domain (needed for android/ios packaging) -package.domain = org.test +package.domain = org.kel # (str) Source code where the main.py live source.dir = . # (list) Source files to include (let empty to include all the files) -source.include_exts = py,png,jpg,kv,atlas,gif,zip +source.include_exts = py,png,jpg,kv,atlas,gif,zip, json, css, ttf,java # (list) List of inclusions using pattern matching #source.include_patterns = assets/*,images/*.png @@ -38,17 +38,22 @@ version = 0.1 # comma separated e.g. requirements = sqlite3,kivy requirements = python3, + android, openssl, sqlite3, - kivy, + kivy, + pyjnius, + libiconv, + libzbar, + pillow, bitmsghash, #git+https://github.com/surbhicis/KivyMD-1.git, git+https://github.com/surbhicis/KivyMD-1#egg=kivymd, kivy-garden, qrcode, - Pillow, msgpack + # (str) Custom source folders for requirements # Sets custom source for any requirements with recipes # requirements.source.kivy = ../../kivy @@ -60,7 +65,7 @@ garden_requirements = qrcode #presplash.filename = %(source.dir)s/data/presplash.png # (str) Icon of the application -#icon.filename = %(source.dir)s/data/icon.png +#icon.filename = %(source.dir)s/logo.png # (str) Supported orientation (one of landscape, portrait or all) orientation = portrait @@ -98,20 +103,23 @@ fullscreen = 0 # (list) Permissions android.permissions = INTERNET, WRITE_EXTERNAL_STORAGE, READ_EXTERNAL_STORAGE -# (int) Android API to use -android.api = 27 +# (int) Target Android API, should be as high as possible. +android.api = 29 -# (int) Minimum API required +# (int) Minimum API your APK will support. android.minapi = 21 # (int) Android SDK version to use android.sdk = 20 # (str) Android NDK version to use -android.ndk = 17c +#android.ndk = 17c + +# (int) Android NDK API to use. This is the minimum API your app will support, it should usually match android.minapi. +#android.ndk_api = 21 # (bool) Use --private data storage (True) or --dir public storage (False) -# android.private_storage = True +#android.private_storage = True # (str) Android NDK directory (if empty, it will be automatically downloaded.) #android.ndk_path = @@ -127,9 +135,18 @@ android.ndk = 17c # when an update is due and you just want to test/build your package # android.skip_update = False +# (bool) If True, then automatically accept SDK license +# agreements. This is intended for automation only. If set to False, +# the default, you will be shown the license when first running +# buildozer. +# android.accept_sdk_license = False + # (str) Android entry point, default is ok for Kivy-based app #android.entrypoint = org.renpy.android.PythonActivity +# (str) Android app theme, default is ok for Kivy-based app +# android.apptheme = "@android:style/Theme.NoTitleBar" + # (list) Pattern to whitelist for the whole project #android.whitelist = @@ -143,11 +160,11 @@ android.ndk = 17c # their classes. Don't add jars that you do not need, since extra jars can slow # down the build process. Allows wildcards matching, for example: # OUYA-ODK/libs/*.jar -#android.add_jars = foo.jar,bar.jar,path/to/more/*.jar +#android.add_jars = libs/*.jar # (list) List of Java files to add to the android project (can be java or a # directory containing the files) -#android.add_src = +#android.add_src = Config.java # (list) Android AAR archives to add (currently works only with sdl2_gradle # bootstrap) @@ -157,12 +174,26 @@ android.ndk = 17c # bootstrap) #android.gradle_dependencies = +# (list) add java compile options +# this can for example be necessary when importing certain java libraries using the 'android.gradle_dependencies' option +# see https://developer.android.com/studio/write/java8-support for further information +# android.add_compile_options = "sourceCompatibility = 1.8", "targetCompatibility = 1.8" + +# (list) Gradle repositories to add {can be necessary for some android.gradle_dependencies} +# please enclose in double quotes +# e.g. android.gradle_repositories = "maven { url 'https://kotlin.bintray.com/ktor' }" +#android.add_gradle_repositories = + +# (list) packaging options to add +# see https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.PackagingOptions.html +# can be necessary to solve conflicts in gradle_dependencies +# please enclose in double quotes +# e.g. android.add_packaging_options = "exclude 'META-INF/common.kotlin_module'", "exclude 'META-INF/*.kotlin_module'" +#android.add_gradle_repositories = + # (list) Java classes to add as activities to the manifest. #android.add_activites = com.example.ExampleActivity -# (str) python-for-android branch to use, defaults to stable -p4a.branch = master - # (str) OUYA Console category. Should be one of GAME or APP # If you leave this blank, OUYA support will not be enabled #android.ouya.category = GAME @@ -179,6 +210,7 @@ p4a.branch = master # (list) Android additional libraries to copy into libs/armeabi #android.add_libs_armeabi = libs/android/*.so #android.add_libs_armeabi_v7a = libs/android-v7/*.so +#android.add_libs_arm64_v8a = libs/android-v8/*.so #android.add_libs_x86 = libs/android-x86/*.so #android.add_libs_mips = libs/android-mips/*.so @@ -193,24 +225,33 @@ p4a.branch = master # project.properties automatically.) #android.library_references = +# (list) Android shared libraries which will be added to AndroidManifest.xml using tag +#android.uses_library = + # (str) Android logcat filters to use #android.logcat_filters = *:S python:D # (bool) Copy library instead of making a libpymodules.so #android.copy_libs = 1 -# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86 -android.arch = armeabi-v7a +# (str) The Android arch to build for, choices: armeabi-v7a, arm64-v8a, x86, x86_64 +android.arch = arm64-v8a # # Python for android (p4a) specific # +# (str) python-for-android fork to use, defaults to upstream (kivy) +#p4a.fork = kivy + +# (str) python-for-android branch to use, defaults to master +p4a.branch = develop + # (str) python-for-android git clone directory (if empty, it will be automatically cloned from github) -p4a.source_dir = /home/cis/Music/androidp4a/python-for-android +#p4a.source_dir = # (str) The directory in which python-for-android should look for your own build recipes (if any) -p4a.local_recipes = /home/cis/navjotrepo/PyBitmessage/src/bitmessagekivy/android/python-for-android/recipes/ +p4a.local_recipes = /home/surbhi/Downloads/peter3/PyBitmessage/src/bitmessagekivy/android/python-for-android/recipes/ # (str) Filename to the hook for p4a #p4a.hook = @@ -228,6 +269,16 @@ p4a.local_recipes = /home/cis/navjotrepo/PyBitmessage/src/bitmessagekivy/android # (str) Path to a custom kivy-ios folder #ios.kivy_ios_dir = ../kivy-ios +# Alternately, specify the URL and branch of a git checkout: +ios.kivy_ios_url = https://github.com/kivy/kivy-ios +ios.kivy_ios_branch = master + +# Another platform dependency: ios-deploy +# Uncomment to use a custom checkout +#ios.ios_deploy_dir = ../ios_deploy +# Or specify URL and branch +ios.ios_deploy_url = https://github.com/phonegap/ios-deploy +ios.ios_deploy_branch = 1.7.0 # (str) Name of the certificate to use for signing the debug version # Get a list of available identities: buildozer ios list_identities @@ -287,4 +338,4 @@ warn_on_root = 1 # # Then, invoke the command line with the "demo" profile: # -#buildozer --profile demo android debug \ No newline at end of file +#buildozer --profile demo android debug diff --git a/src/main.py b/src/main.py index 22ea7c3e..4adbb1ae 100644 --- a/src/main.py +++ b/src/main.py @@ -1,8 +1,8 @@ """This module is for thread start.""" import state +from bitmessagemain import main if __name__ == '__main__': state.kivy = True - print("Kivy Loading for PyBitmessage......") - from bitmessagemain import main - main() + print("Kivy Loading......") + main() \ No newline at end of file