Coding python on android - android

First of all, sorry. I am new to both programming and programming on my android device, but for some reason when I go to compile this code and run it using Python For Android. It keeps returning this error:
File "/storage/emulated/programming/pass.py", line 4, in
username = input("Username: ") File"", line 1, in
NameError: name 'user' is not defined
security = 0
username = ""
while not username:
username = input("username: ")
password = ""
while not password:
password = input("password: ")
if username == "user" and password == "pass":
security = 5
print (" Hello, security level is:" , security)
else:
print("invalid login")
Now, when I run this same bit of code on my PC, I do not get this error. Is anyone here familiar with writing Python code with Python For Android and Droidedit? I have installed all available modules.

Im guessing p4a is not py3.0+ therefore you need raw_input not input
in python2 raw_input is the same as input in python3+
using input in python2 is the same as doing eval(input("Username:")) in python 3
>>> x = raw_input("Enter Equation:")
Enter Equation: 5 + 3
>>> print repr(x)
'5 + 3'
>>> y = input("Enter Equation:") #this is the same as eval(input(msg)) in py3+
Enter Equation: 5 + 3
>>> print repr(y)
`8`
some further info regarding your error specifically. in python2 input attempts to evaluate the user input into python code. you are entering "user" as the username. python then tries to make it into code interpreting it as a variable. if for example you entered 543 for the username it would work fine. also if you entered "user" including the quotes it would work fine as both would evaluate down to python values (the quotes make it a string instead of a variable, and python knows what ints are)

Related

ANDROID VOLLEY + JWT TOKEN AUTHENTICATION + DJANGO REST FRAMEWORK

I am currently developing an android chat app. I am very new to Android Studio, JWT Token Authorization, and Django Rest Framework. Right now I am having issue to work on the Django side.
So basically I was setting up a login page from my Android, and I want it to login using phone number and password as the needed credentials. However, I also want to use JWT Token Auth to make my application more secure.
Currently I have my project urls.py pointing to one of the JWT Token API
urls.py
from django.contrib import admin
from django.urls import path,include
from django.conf.urls import include, url
from rest_framework_simplejwt import views as jwt_views
urlpatterns = [
path('admin/', admin.site.urls),
path('account/',include('restaccount.urls')) ,
path('api/token/', jwt_views.TokenObtainPairView.as_view(), name='token_obtain_pair'),
path('api/token/refresh/', jwt_views.TokenRefreshView.as_view(), name='token_refresh'),
]
This would lead to the server page which was
*PS : The phone number fields should be the default username field..(I have made some trial modifications on my code prior I post this).
I also have set up a models that was inherit from AbstractUser
models.py
class RegisterUser(AbstractUser):
phone_number = PhoneField(name='phone_number',unique=True)
birthday = models.DateField(name ='birthday',null= True)
nickname = models.CharField(max_length=100,name = 'nickname')
def __str__(self):
return self.phone_number
Currently I have tried to make a lot of modifications to my model, like :
change username = None
REQUIRED_FIELDS = []
USERNAME_FIELDS = 'phone_number'
I realize that the Token Obtain Pair View is following the Django Administration page in terms of the information that you needed (username and password).
However when I modified, I try to create superuser and try to login too Django Admin with my modified data..But I still cannot log in.. Also, I try to get token from the superuser that I have made, but it will response in "detail": "No active account found with the given credentials"
Can somebody enlighten me of the steps that I should take now?? I have tried to look for solutions but none of them solve my problem
Here's the point TLDR:
I want my app to Login using phone number and password and want to use JWT Token Auth to make it secure.
I realize the ObtainTokenPair view follows Django Admin credentials, so I have tried to modify my backend to be "log in" using phone number and password.
After I modified, I can't login to Django Admin and cannot get token with the superuser I created.
Here some of the related file attach:
Settings.py
"""
Django settings for androidapp project.
Generated by 'django-admin startproject' using Django 3.0.7.
For more information on this file, see
https://docs.djangoproject.com/en/3.0/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/3.0/ref/settings/
"""
import os
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/3.0/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '6qdk058^8b2#-pnw!cr1pbd(sao)vj+v69&4874zjh95xu7pg)'
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ['172.31.120.211',]
# Application definition
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'restaccount',
]
MIDDLEWARE = [
'django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
]
ROOT_URLCONF = 'androidapp.urls'
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [],
'APP_DIRS': True,
'OPTIONS': {
'context_processors': [
'django.template.context_processors.debug',
'django.template.context_processors.request',
'django.contrib.auth.context_processors.auth',
'django.contrib.messages.context_processors.messages',
],
},
},
]
WSGI_APPLICATION = 'androidapp.wsgi.application'
# Database
# https://docs.djangoproject.com/en/3.0/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'Orbital',
'USER' :'SomeUser',
'PASSWORD':'Pass',
'HOST' : 'localhost',
'PORT' : '',
}
}
# Password validation
# https://docs.djangoproject.com/en/3.0/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
},
{
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
},
]
# Internationalization
# https://docs.djangoproject.com/en/3.0/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'UTC'
USE_I18N = True
USE_L10N = False
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/3.0/howto/static-files/
STATIC_URL = '/static/'
AUTH_USER_MODEL = 'restaccount.RegisterUser'
#FORMAT FOR DATE INPUT
DATE_INPUT_FORMATS = ('%d-%m-%Y', '%d/%m/%Y', '%d/%m/%y', '%d %b %Y',
'%d %b, %Y', '%d %b %Y', '%d %b, %Y', '%d %B, %Y',
'%d %B %Y')
#Format for date-time input format
DATETIME_INPUT_FORMATS = ('%d/%m/%Y %H:%M:%S', '%d/%m/%Y %H:%M', '%d/%m/%Y',
'%d/%m/%y %H:%M:%S', '%d/%m/%y %H:%M', '%d/%m/%y',
'%Y-%m-%d %H:%M:%S', '%Y-%m-%d %H:%M', '%Y-%m-%d')
# Adding REST_FRAMEWORK SETTING WITH JWT AUTHENTICATION
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': [
'rest_framework_simplejwt.authentication.JWTAuthentication',
],
}
# AUTHENTICATION_BACKENDS = (
# 'django.contrib.auth.backends.ModelBackend',
# 'restaccount.backends.UserBackend'
# )
RegisterUserManager inside models.py
class RegisterUserManager(BaseUserManager):
def create_user(self, phone_number,password, **extra_fields):
if not phone_number:
raise ValueError('The phone number must be set')
user = self.model(
phone_number=phone_number,
password = password,
**extra_fields)
user.save()
return user
def create_superuser(self,phone_number,password, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
# print(phone_number)
if extra_fields.get('is_staff') is not True:
raise ValueError(_('Superuser must have is_staff=True.'))
if extra_fields.get('is_superuser') is not True:
raise ValueError(_('Superuser must have is_superuser=True.'))
return self.create_user(phone_number, password,**extra_fields)
Its quite difficult to pin point the bug without getting hands-on to the actual project. I can't not find the bug or fix your project. that you have to do on your own. But I can surely share what I think would help you avoid bug and fix your project.
what I could understand
you want a custom user model
your want to use jwt authentication
so, let's begin. User model and authentication are two different things. create Custom User model first.
firstly, remove all users from database
create Custom User model following this 'A full example' exactly (check by creating superuser if custom user model is working properly, if not that means you missed something try again)
If you have successfully created custom user model that means you now have substituted 'username' with 'phone number' (in your case)
for authentication you can use custom authentication or as you tried you can use existing packages. Configure it to act as default authentication backend.
your choice of authentication package should take username and password, check if there is a user match those credentials create a token and return that token. you don't need to modify the authentication process you just provide username field(phone number) and password. Now here you might need to do something like
{username: phone_number, password: password}
because your authentication package might not support custom user.
hope it helps.

ADB command from macOS application with special characters

I want to pull a file from my android device through an adb command from my macOS application.
Everything works perfect with the code below, except when the name of the file I want to pull contains special characters like german umlauts (äöüÄÖÜ).
I get this error:
adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory.
But when I use the command adb pull /storage/emulated/0/Download/Böse ~/Desktop from within the Terminal.app, the file will be pulled to my computer.
The strange thing here is that if I copy the substring /storage/emulated/0/Download/Böse from the Xcode console output, the command is also not working within the Terminal.app until I delete the ö and replace it with an ö from my keyboard input.
I tried replacing the ö with the unicode representation \u{00f6}, but this has no effect (but the console output still shows an ö but the 'wrong' encoded one.
// Configure task.
let task = Process()
task.launchPath = "~/Library/Android/sdk/platform-tools/adb"
task.arguments = ["pull", "/storage/emulated/0/Download/Böse", "~/Desktop"]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
// adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory
print(output)
I found the following in the documentation, how the Process handles the arguments that I provide:
The NSTask object converts both path and the strings in arguments to appropriate C-style strings (using fileSystemRepresentation) before passing them to the task via argv[] . The strings in arguments do not undergo shell expansion, so you do not need to do special quoting, and shell variables, such as $PWD, are not resolved.
It seems like I am not the only one with this problem, and I found this workaround:
How to work around NSTask calling -[NSString fileSystemRepresentation] for arguments, but I was not able to make it work with Swift.
As a workaround I am now writing my adb command to a file and execute it from a bash command in my application.
let source = "/storage/emulated/0/Download/Böse"
let destination = "~/Desktop"
guard let uniqueURL = URL(string: destination + "/" + ProcessInfo.processInfo.globallyUniqueString) else { return }
// Write command to file
let scriptContent = "#!/bin/bash\n~/Library/Android/sdk/platform-tools/adb pull -a \"" + source + "\" \"" + destination + "\""
try? scriptContent.write(to: uniqueURL, atomically: false, encoding: .utf8)
// Configure task.
let task = Process()
task.environment = ["LC_ALL": "de_DE.UTF-8", "LANG": "de_DE.UTF-8"]
task.launchPath = "/bin/bash"
task.arguments = [uniqueURL.path]
// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
try? task.run()
// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()
print(output)
Even though this is working for now, it is not a satisfactory solution as it is not very elegant and not efficient too, so any improvements or better answers are welcome.

Firebase notifications in debug environment are sent to production Android clients

I have a great headache.
I have a running 'web-app', writed whith Rails4, in production hosted on a Google Compute Engine virtual machine with Ubuntu 14.04, where I use Rpush gem/Firebase for notification to an Android app 'my-app'.
Locally I use a similar configuration for development: an environment rvm with same Rails version.
Simultaneously, with AndroidStudio, I'm developing 'my-app' android app.
On Ubuntu 16.04.
When Rails/Rpush send a notification, I receive it on 'my-app'.
So I controls both sides of notification process (except Firebase as middle tier).
Great.
It worked fine until some days ago.
Production enviroment continues to working well.
Locally, on development, when 'web-app' send a notification (through RPush/Firebase) I don't receive any kind of message, but I receive it in production, on 'released-version' of 'my-app' !!!
Normally, working local, when 'local' 'web-app' send notification, 'local' 'my-app' receive it;
in production, when 'host' 'we-app' send notification, 'released-version' of 'my-app' receive it.
For a few days is like if, in Firebase, in middle tier, each notification is broadcasted through 'released-version' of 'my-app', also if came from 'local' debug environment !!
Same releases for both envs.
It worked well until a few days ago.
Surely I've touched somethings ... the project is in progess.
I've much debugged, I've controlled many times configurations (local, host and Firebase) read many logs without results.
Everything seems working well !!
Someone know some ways to show me how debugging/understand this mysterious (for me) behavior ?
In Rails, when a message is saved, is triggered a method to push notification as described in GitHub by RPush repository.
In Android, in class 'MyFirebaseMessagingService extends FirebaseMessagingService', on overrided method 'onMessageReceived(RemoteMessage remoteMessage)' I receive messages (notification or data) - following 'quickstart-android/messaging' example.
In Firebase I have a project where I take 'Server Key' and 'google-services.json'.
My headache is growing.
Any advice is welcome.
UPDATE 20180326
I upgrade my question with code executed when sending message, configuration and an extract of rpush log (Rails server side - both local and hosted).
Rails method triggered after save 'Message'
def notify_gcm(data)
if Rpush::Gcm::App.find_by_name(<firebase_app>).nil?
app = Rpush::Gcm::App.new
app.name = <firebase_app>
app.auth_key = <firebase-server_key>
app.connections = 1
app.save!
end
n = Rpush::Gcm::Notification.new
n.app = Rpush::Gcm::App.find_by_name(<firebase_app>)
n.delay_while_idle = true
n.registration_ids = [<device_token>, ...]
n.priority = 'high'
n.content_available = true
# notification type: DATA MESSAGE
n.data = { data: { message: data[:message]["content"] }, notificationdata: { body: ..., title: ..., icon: ... }
}
n.save!
Rpush.push
end
config/initializers/rpush
Rpush.configure do |config|
config.client = :active_record
config.push_poll = 5
config.batch_size = 100
config.pid_file = 'tmp/rpush.pid'
config.log_file = 'log/rpush.log'
config.log_level = (defined?(Rails) && Rails.logger) ? Rails.logger.level : ::Logger::Severity::ERROR
end
Rpush log
BEGIN
INSERT INTO `rpush_notifications` (`type`, `app_id`, `delay_while_idle`, `registration_ids`, `priority`, `content_available`, `data`, `created_at`, `updated_at`) VALUES (...)
COMMIT
SELECT `rpush_apps`.* FROM `rpush_apps`[<firebase_app>] Starting 1 dispatcher...
SELECT COUNT(*) FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.719515'))
BEGIN
SELECT `rpush_notifications`.* FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.720521')) ORDER BY created_at ASC LIMIT 100 FOR UPDATE
UPDATE `rpush_notifications` SET processing = 1 WHERE rpush_notifications`.`id` = 210
COMMIT
SELECT COUNT(*) FROM `rpush_notifications` WHERE (processing = 0 AND delivered = 0 AND failed = 0 AND (deliver_after IS NULL OR deliver_after < '2018-03-25 10:27:22.774452'))
SELECT `rpush_apps`.* FROM `rpush_apps` WHERE `rpush_apps`.`id` = 1 LIMIT 1
[<firebase_app>] 210 sent to ... <proper registration_ids>
Rpush is started as a daemon by commandline:
rpush start -e production
SOLVED
Gemfile
removed gem 'rails_12factor', group :production
this it was been previously removed to hosted (production) :(

Moving a chat server application from parse.com to google app engine

We are planning to move a chat server application resides on parse.com to Google app engine's datastore since parse is going to shutdown it's service on Jan 2017. I think this should be possible through App engine's XMPP API. Not sure, I love to hear from you..
Currently I'm testing with this code provided by Google
# Copyright 2009 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Crowdguru sample application using the XMPP service on Google App Engine."""
import datetime
from google.appengine.api import datastore_types
from google.appengine.api import xmpp
from google.appengine.ext import ndb
from google.appengine.ext.webapp import xmpp_handlers
import webapp2
from webapp2_extras import jinja2
PONDER_MSG = 'Hmm. Let me think on that a bit.'
TELLME_MSG = 'While I\'m thinking, perhaps you can answer me this: {}'
SOMEONE_ANSWERED_MSG = ('We seek those who are wise and fast. One out of two '
'is not enough. Another has answered my question.')
ANSWER_INTRO_MSG = 'You asked me: {}'
ANSWER_MSG = 'I have thought long and hard, and concluded: {}'
WAIT_MSG = ('Please! One question at a time! You can ask me another once you '
'have an answer to your current question.')
THANKS_MSG = 'Thank you for your wisdom.'
TELLME_THANKS_MSG = THANKS_MSG + ' I\'m still thinking about your question.'
EMPTYQ_MSG = 'Sorry, I don\'t have anything to ask you at the moment.'
HELP_MSG = ('I am the amazing Crowd Guru. Ask me a question by typing '
'\'/tellme the meaning of life\', and I will answer you forthwith! '
'To learn more, go to {}/')
MAX_ANSWER_TIME = 120
class IMProperty(ndb.StringProperty):
"""A custom property for handling IM objects.
IM or Instant Message objects include both an address and its protocol. The
constructor and __str__ method on these objects allow easy translation from
type string to type datastore_types.IM.
"""
def _validate(self, value):
"""Validator to make sure value is an instance of datastore_types.IM.
Args:
value: The value to be validated. Should be an instance of
datastore_types.IM.
Raises:
TypeError: If value is not an instance of datastore_types.IM.
"""
if not isinstance(value, datastore_types.IM):
raise TypeError('expected an IM, got {!r}'.format(value))
def _to_base_type(self, value):
"""Converts native type (datastore_types.IM) to datastore type (string).
Args:
value: The value to be converted. Should be an instance of
datastore_types.IM.
Returns:
String corresponding to the IM value.
"""
return str(value)
def _from_base_type(self, value):
"""Converts datastore type (string) to native type (datastore_types.IM).
Args:
value: The value to be converted. Should be a string.
Returns:
String corresponding to the IM value.
"""
return datastore_types.IM(value)
class Question(ndb.Model):
"""Model to hold questions that the Guru can answer."""
question = ndb.TextProperty(required=True)
asker = IMProperty(required=True)
asked = ndb.DateTimeProperty(required=True, auto_now_add=True)
suspended = ndb.BooleanProperty(required=True)
assignees = IMProperty(repeated=True)
last_assigned = ndb.DateTimeProperty()
answer = ndb.TextProperty(indexed=True)
answerer = IMProperty()
answered = ndb.DateTimeProperty()
#staticmethod
#ndb.transactional
def _try_assign(key, user, expiry):
"""Assigns and returns the question if it's not assigned already.
Args:
key: ndb.Key: The key of a Question to try and assign.
user: datastore_types.IM: The user to assign the question to.
expiry: datetime.datetime: The expiry date of the question.
Returns:
The Question object. If it was already assigned, no change is made.
"""
question = key.get()
if not question.last_assigned or question.last_assigned < expiry:
question.assignees.append(user)
question.last_assigned = datetime.datetime.now()
question.put()
return question
#classmethod
def assign_question(cls, user):
"""Gets an unanswered question and assigns it to a user to answer.
Args:
user: datastore_types.IM: The identity of the user to assign a
question to.
Returns:
The Question entity assigned to the user, or None if there are no
unanswered questions.
"""
question = None
while question is None or user not in question.assignees:
# Assignments made before this timestamp have expired.
expiry = (datetime.datetime.now()
- datetime.timedelta(seconds=MAX_ANSWER_TIME))
# Find a candidate question
query = cls.query(cls.answerer == None, cls.last_assigned < expiry)
# If a question has never been assigned, order by when it was asked
query = query.order(cls.last_assigned, cls.asked)
candidates = [candidate for candidate in query.fetch(2)
if candidate.asker != user]
if not candidates:
# No valid questions in queue.
break
# Try and assign it
question = cls._try_assign(candidates[0].key, user, expiry)
# Expire the assignment after a couple of minutes
return question
#ndb.transactional
def unassign(self, user):
"""Unassigns the given user from this question.
Args:
user: datastore_types.IM: The user who will no longer be answering
this question.
"""
question = self.key.get()
if user in question.assignees:
question.assignees.remove(user)
question.put()
#classmethod
def get_asked(cls, user):
"""Returns the user's outstanding asked question, if any.
Args:
user: datastore_types.IM: The identity of the user asking.
Returns:
An unanswered Question entity asked by the user, or None if there
are no unanswered questions.
"""
query = cls.query(cls.asker == user, cls.answer == None)
return query.get()
#classmethod
def get_answering(cls, user):
"""Returns the question the user is answering, if any.
Args:
user: datastore_types.IM: The identity of the user answering.
Returns:
An unanswered Question entity assigned to the user, or None if there
are no unanswered questions.
"""
query = cls.query(cls.assignees == user, cls.answer == None)
return query.get()
def bare_jid(sender):
"""Identify the user by bare jid.
See http://wiki.xmpp.org/web/Jabber_Resources for more details.
Args:
sender: String; A jabber or XMPP sender.
Returns:
The bare Jabber ID of the sender.
"""
return sender.split('/')[0]
class XmppHandler(xmpp_handlers.CommandHandler):
"""Handler class for all XMPP activity."""
def unhandled_command(self, message=None):
"""Shows help text for commands which have no handler.
Args:
message: xmpp.Message: The message that was sent by the user.
"""
message.reply(HELP_MSG.format(self.request.host_url))
def askme_command(self, message=None):
"""Responds to the /askme command.
Args:
message: xmpp.Message: The message that was sent by the user.
"""
im_from = datastore_types.IM('xmpp', bare_jid(message.sender))
currently_answering = Question.get_answering(im_from)
question = Question.assign_question(im_from)
if question:
message.reply(TELLME_MSG.format(question.question))
else:
message.reply(EMPTYQ_MSG)
# Don't unassign their current question until we've picked a new one.
if currently_answering:
currently_answering.unassign(im_from)
def text_message(self, message=None):
"""Called when a message not prefixed by a /cmd is sent to the XMPP bot.
Args:
message: xmpp.Message: The message that was sent by the user.
"""
im_from = datastore_types.IM('xmpp', bare_jid(message.sender))
question = Question.get_answering(im_from)
if question:
other_assignees = question.assignees
other_assignees.remove(im_from)
# Answering a question
question.answer = message.arg
question.answerer = im_from
question.assignees = []
question.answered = datetime.datetime.now()
question.put()
# Send the answer to the asker
xmpp.send_message([question.asker.address],
ANSWER_INTRO_MSG.format(question.question))
xmpp.send_message([question.asker.address],
ANSWER_MSG.format(message.arg))
# Send acknowledgement to the answerer
asked_question = Question.get_asked(im_from)
if asked_question:
message.reply(TELLME_THANKS_MSG)
else:
message.reply(THANKS_MSG)
# Tell any other assignees their help is no longer required
if other_assignees:
xmpp.send_message([user.address for user in other_assignees],
SOMEONE_ANSWERED_MSG)
else:
self.unhandled_command(message)
def tellme_command(self, message=None):
"""Handles /tellme requests, asking the Guru a question.
Args:
message: xmpp.Message: The message that was sent by the user.
"""
im_from = datastore_types.IM('xmpp', bare_jid(message.sender))
asked_question = Question.get_asked(im_from)
if asked_question:
# Already have a question
message.reply(WAIT_MSG)
else:
# Asking a question
asked_question = Question(question=message.arg, asker=im_from)
asked_question.put()
currently_answering = Question.get_answering(im_from)
if not currently_answering:
# Try and find one for them to answer
question = Question.assign_question(im_from)
if question:
message.reply(TELLME_MSG.format(question.question))
return
message.reply(PONDER_MSG)
class XmppPresenceHandler(webapp2.RequestHandler):
"""Handler class for XMPP status updates."""
def post(self, status):
"""POST handler for XMPP presence.
Args:
status: A string which will be either available or unavailable
and will indicate the status of the user.
"""
sender = self.request.get('from')
im_from = datastore_types.IM('xmpp', bare_jid(sender))
suspend = (status == 'unavailable')
query = Question.query(Question.asker == im_from,
Question.answer == None,
Question.suspended == (not suspend))
question = query.get()
if question:
question.suspended = suspend
question.put()
class LatestHandler(webapp2.RequestHandler):
"""Displays the most recently answered questions."""
#webapp2.cached_property
def jinja2(self):
"""Cached property holding a Jinja2 instance.
Returns:
A Jinja2 object for the current app.
"""
return jinja2.get_jinja2(app=self.app)
def render_response(self, template, **context):
"""Use Jinja2 instance to render template and write to output.
Args:
template: filename (relative to $PROJECT/templates) that we are
rendering.
context: keyword arguments corresponding to variables in template.
"""
rendered_value = self.jinja2.render_template(template, **context)
self.response.write(rendered_value)
def get(self):
"""Handler for latest questions page."""
query = Question.query(Question.answered > None).order(
-Question.answered)
self.render_response('latest.html', questions=query.fetch(20))
APPLICATION = webapp2.WSGIApplication([
('/', LatestHandler),
('/_ah/xmpp/message/chat/', XmppHandler),
('/_ah/xmpp/presence/(available|unavailable)/', XmppPresenceHandler),
], debug=True)
If a user selects another user whom he wants to chat with should call API url /_ah/xmpp/message/chat/ which automatically invokes XmppHandler handler.
('/_ah/xmpp/message/chat/', XmppHandler)
And my doubt is, If he post a message like foo on that particular chat does it automatically invokes text_message method exists in XmppHandler ? Is there we need to configure xmpp on client side also?
For the client api compatible and db migration, you can host your own parse-server.
There is a simple express project to use parse-server.
https://github.com/ParsePlatform/parse-server-example
They are lots of deploy guide to each cloud-platform
Google App Engine
Heroku and mLab
AWS and Elastic Beanstalk
Digital Ocean
NodeChef
Microsoft Azure
Pivotal Web Services
Back4app
Or you can host your nodejs server with your domain name.
If you want to do something different from parse, you can send a pull request to parse-server. LiveQuery is the extra function created by contributors.
For more details, see the link from Parse.com , github wiki, and community links.
Parse has provided detailed information regarding the migration
process and how to move our app from their serviers to a seperately
hosted mongoDB instance and cloud company. Parse suggests the
migration be made in two steps:
The database is migrated to a service like MongoLab or ObjectRocket.
The server be migrated to a cloud hosting company like AWS, Google App Engine, or Heroku.
Parse has also put suggested deadlines in place:
they suggest that by April 28, 2016 the database be migrated and by
July 28, 2016, the server be migrated properly.
This will give you ample time to work out any bugs and ensure your app functions properly with no downtime!
A Backend-as-a-Service like parse.com coupled two aspects of what’s known as a backend into one: the server and database. The server, which manipulates the database, performs queries, fetches information, and other work-intensive tasks, interacts with the database. The two work hand-in-hand to form a backend.
With Parse going away, we must deal with the server and database
seperately.
Parse has already provided detailed info and easy migration tool for database to Mongodb hosted on any cloud.
Also it is easy to setup the node based parse server on any cloud platform including Google App Engine:
The easiest way to get Parse server running on Google Cloud is to start with the sample out on GitHub.

Converting .db to .vcf

I accidentally deleted my contacts and i don't have a backup for that now i got the contacts2.db and i am trying to covert the .db to .vcf. Now i am using Ruby to convert the file and here is what i did
gem install sqlite3
gem install vpim
path to contacts2-to-vcard.rb/contacts2-to-vcard.rb > contacts.vcf
i always says 'Access Denied.' And i set the folder to full control but whenever i run that command it change to read only, by the way i am using windows 8. Any help? Or is there a alternate why to convert .db to .vcf? TIA
Yank it out of the DB (this is all in Ruby):
require 'sqlite3'
path_to_contactsdb_file = "/SAMPLE/PATH/TO/contacts2.db"
db = SQLite3::Database.new path_to_contactsdb_file
raw_contacts = db.execute("select _id,display_name from raw_contacts")
contacts = {}
raw_contacts.each do |x|
contacts[x[1]] = {}
contacts[x[1]]['rcid'] = x[0]
contacts[x[1]]['nums'] = db.execute("select normalized_number from phone_lookup where raw_contact_id=" + x[0].to_s)
end
Pull it to CSV:
output_filepath = "/SAMPLE/EXAMPLE/FILEPATH"
csv = ""
contacts.each do |k,v|
csv += '"' + k + '",'
v['nums'].each do |num|
csv += '"' + num[0] + '",'
end
csv += "\n"
end
File.open(output_filepath,"w") {|file| file.write(csv) }
Then you can use a CSV import app, do it through Google contacts import through CSV, etc.. You can send me a fruit basket.
If it MUST be in a VCF format, then just change the output syntax of the CSV. Look up a sample VCF file, I couldn't be bothered.
I've been trying to use Dustin van Schouwen's code to do this task. I wanted to thank him for it, first of all, and then mention a few details I needed to add/change to make it work for me:
This line:
db = SQLite3::Database.new path_to_contactsdb_file
I changed to:
db = SQLite3::Database.new ("contacts2.db")
As when using the previous one, even though it doesn't give an error, it doesn't seem to actually connect to the database (I think it creates an empty one).
The other change I needed to do was at this other line:
csv += '"' + k + '",
If "k" is nil, the code will fail, so I introduced an if (ternary syntax) to solve it, and it worked fine:
csv += '"' + (k == nil ? "" : k) + '",'
A bit late for OP sorry. I can't give tips on ruby anyway.
But I stumbled here when searching a solution for my own needs.
I finally came up with a python solution:
https://gitlab.com/Arnaudv6/contacts2.db-2-vcard
based on previous works documented on above page.
Please refer to "todo" section at beginning of the script
for details on what is not implemented to date.

Categories

Resources