├── MANIFEST.in ├── test ├── testimg.png └── test_jodel_api.py ├── src └── jodel_api │ ├── protos │ ├── __init__.py │ ├── mcs.proto │ ├── checkin.proto │ ├── checkin_pb2.py │ └── mcs_pb2.py │ ├── __init__.py │ ├── gcmhack.py │ └── jodel_api.py ├── setup.cfg ├── ISSUE_TEMPLATE.md ├── LICENSE.txt ├── .travis.yml ├── .gitignore ├── setup.py └── README.rst /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.txt 2 | include README.rst 3 | include test/testimg.png -------------------------------------------------------------------------------- /test/testimg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nborrmann/jodel_api/HEAD/test/testimg.png -------------------------------------------------------------------------------- /src/jodel_api/protos/__init__.py: -------------------------------------------------------------------------------- 1 | from jodel_api.protos import checkin_pb2 2 | from jodel_api.protos import mcs_pb2 3 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest 3 | 4 | [tool:pytest] 5 | addopts = --verbose --showlocals -ra --no-success-flaky-report 6 | 7 | [metadata] 8 | description-file = README.rst 9 | -------------------------------------------------------------------------------- /src/jodel_api/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, print_function, unicode_literals) 2 | 3 | from jodel_api.protos import mcs_pb2 4 | from jodel_api.protos import checkin_pb2 5 | from jodel_api.gcmhack import AndroidAccount 6 | from jodel_api.jodel_api import * 7 | -------------------------------------------------------------------------------- /ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ## Issue 2 | 3 | ... 4 | 5 | ## Environment 6 | 7 | If you're reporting a bug, please attach the output of the following commands: 8 | 9 | ``` 10 | $ pip show jodel_api 11 | $ pip -V 12 | $ python -V 13 | $ python -c "import jodel_api; print(jodel_api.JodelAccount.version); print(jodel_api.JodelAccount.secret)" 14 | ``` -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Nils Borrmann 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: python 2 | python: 3 | - 2.7 4 | - 3.3 5 | install: 6 | - pip install codecov 7 | - pip install flaky 8 | - python setup.py -q install 9 | script: 10 | - coverage run --source=jodel_api -m pytest -v -l -ra --no-success-flaky-report 11 | after_success: 12 | codecov 13 | deploy: 14 | true: 15 | branch: master 16 | distributions: sdist bdist_wheel 17 | user: nborrmann 18 | provider: pypi 19 | password: 20 | secure: "S5EI4q+Wu04YprKfpUMGVePCry6FXHYjB4nufz0FzwE1ZsDCZ46uaVVDV4sf6ip1bQrVpZkmtK+33V/qbghjpWGq6tTLFkEMtO7YX7YWK2HCSQb1Lgot0e/VWcgp2cExvqzwMtH1JqhNcazdsPWOGvlDLXZc9OOgBbJN9uB4S2vLQsBhLy9oXzcPS6GqruWW7ewoOG7l4XQBkAuf3nX14mouej/7OocMK4cFKdQtRIFNBgGYZ0FNROvBsxoK463IMqGIIHV+YpqBwTMEPyiBuDqye0ViSn146HEyf7qmDzpU1iDqfXXRE5EjS6er1y5HOsHaigNcSijVZdry3IPgPD5LCQbbD9UXMlodNtVav8MU1joENVsDR7wtkqwlIkju91xIJEulQ3Y9s1Wfi6RsmheHBrRJ5ZZXP+UuDBRuhecIfN4MKdDNX1fDEyMlyjnHzKQnk+I5Jq3TyULi2QbnJMAlRpD0dC+U93Sh33AtQmdZS3rbhUOSaI1DOzdN1JawsG99fO9+RP6YqwnEXe+esDUWwIr5lFYPnsh3vmt7hcSIYeJN50PWQouEdEhOXtcx0pm0dizNfIJCesGb39ADM1P1c/yWrJr8WmDfI+j3ERu2e6Lx977B4kCUKGbsZx45EIH0H4m5KqVHKq+QDc9bVJ2/NqajQSpEdvxms7c4dD0=" 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *,cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | 93 | # Rope project settings 94 | .ropeproject 95 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup, find_packages 2 | import os 3 | 4 | with open(os.path.join(os.path.dirname(__file__), 'README.rst')) as f: 5 | long_description = f.read() 6 | 7 | setup(name='jodel_api', 8 | version='1.2.11', 9 | description='Unoffical Python Interface to the Jodel API', 10 | long_description=long_description, 11 | url='https://github.com/nborrmann/jodel_api', 12 | author='Nils Borrmann', 13 | author_email='n.borrmann@googlemail.com', 14 | license='MIT', 15 | classifiers=[ 16 | 'Development Status :: 5 - Production/Stable', 17 | 'License :: OSI Approved :: MIT License', 18 | 'Intended Audience :: Developers', 19 | 'Programming Language :: Python :: 2', 20 | 'Programming Language :: Python :: 2.7', 21 | 'Programming Language :: Python :: 3', 22 | 'Programming Language :: Python :: 3.3', 23 | 'Programming Language :: Python :: 3.4', 24 | 'Programming Language :: Python :: 3.5', 25 | 'Topic :: Internet :: WWW/HTTP', 26 | 'Topic :: Internet :: WWW/HTTP :: Dynamic Content :: Message Boards', 27 | 'Topic :: Software Development :: Libraries :: Python Modules', 28 | ], 29 | keywords='jodel', 30 | package_dir={'': 'src'}, 31 | install_requires=['requests', 'future', 'mock', 'varint', 'protobuf'], 32 | packages=find_packages('src'), 33 | setup_requires=['pytest-runner', ], 34 | tests_require=['pytest', 'flaky'], 35 | zip_safe=False) 36 | -------------------------------------------------------------------------------- /src/jodel_api/gcmhack.py: -------------------------------------------------------------------------------- 1 | from __future__ import (absolute_import, print_function, unicode_literals) 2 | from future.utils import raise_from 3 | 4 | import sys 5 | import random 6 | import requests 7 | import string 8 | import time 9 | import ssl 10 | import socket 11 | import varint 12 | import json 13 | from jodel_api.protos import checkin_pb2 14 | from jodel_api.protos import mcs_pb2 15 | import select 16 | import struct 17 | 18 | class GcmException(Exception): 19 | pass 20 | 21 | 22 | class AndroidAccount: 23 | sock = None 24 | responseTag = 0 25 | 26 | def __init__(self, android_id=None, security_token=None, **kwargs): 27 | self.session = requests.Session() 28 | 29 | if android_id and security_token: 30 | self.android_id = android_id 31 | self.security_token = security_token 32 | 33 | else: 34 | try: 35 | self._google_checkin(**kwargs) 36 | except: 37 | raise 38 | 39 | def _google_checkin(self, **kwargs): 40 | # most minimal checkin request possible 41 | cr = checkin_pb2.CheckinRequest() 42 | cr.checkin.build.sdkVersion = 18 43 | cr.version = 3 44 | cr.fragment = 0 45 | 46 | data = cr.SerializeToString() 47 | headers = {"Content-type": "application/x-protobuffer", 48 | "Accept-Encoding": "gzip", 49 | "User-Agent": "Android-Checkin/2.0 (vbox86p JLS36G); gzip"} 50 | r = self.session.post("https://android.clients.google.com/checkin", headers=headers, data=data, **kwargs) 51 | 52 | if r.status_code == 200: 53 | cresp = checkin_pb2.CheckinResponse() 54 | cresp.ParseFromString(r.content) 55 | self.android_id, self.security_token = cresp.androidId, cresp.securityToken 56 | else: 57 | raise GcmException(r.text) 58 | 59 | def get_push_token(self, **kwargs): 60 | headers = {"Authorization": "AidLogin {}:{}".format(self.android_id, self.security_token)} 61 | 62 | data = {'app': 'com.tellm.android.app', 63 | 'app_ver': '1001800', 64 | 'cert': 'a4a8d4d7b09736a0f65596a868cc6fd620920fb0', 65 | 'device': str(self.android_id), 66 | 'sender': '425112442765', 67 | 'X-appid': "".join(random.choice(string.ascii_letters + string.digits) for _ in range(11)), 68 | 'X-scope': 'GCM' } 69 | 70 | r = self.session.post("https://android.clients.google.com/c2dm/register3", headers=headers, data=data, **kwargs) 71 | if r.status_code == 200 and "token" in r.text: 72 | return r.text.split("=")[1] 73 | else: 74 | raise GcmException(r.text) 75 | 76 | def receive_verification_from_gcm(self, retry=True): 77 | # Return the last verification_code that we receive. 78 | # Note: We cannot return on the first verification_code because the server sometimes sends 79 | # the same code twice. 80 | self._establish_connection() 81 | verification_data = None 82 | 83 | try: 84 | while True: 85 | # Sometimes the server sends a response_tag and length but doesn't send the actual content, 86 | # so we need to remeber them and read just the content on the next call. 87 | if not self.responseTag: 88 | self.responseTag = ord(self._rcv_exact(1)) 89 | self.length = varint.decode_stream(self.sock) 90 | 91 | msg = self._rcv_exact(self.length) 92 | self.counter += 1 93 | 94 | if self.responseTag == 3: 95 | pass # login 96 | 97 | elif self.responseTag == 4: 98 | raise Exception("socket closed by server") 99 | 100 | elif self.responseTag == 8: 101 | dms = mcs_pb2.DataMessageStanza() 102 | dms.ParseFromString(msg) 103 | 104 | message_type, data = "", None 105 | for app_data in dms.app_data: 106 | if app_data.key == "message_type_id": 107 | message_type = app_data.value 108 | elif app_data.key == "payload": 109 | data = app_data.value 110 | 111 | if dms.category == "com.tellm.android.app" and message_type == "16": 112 | verification_data = data 113 | 114 | self.responseTag, self.length = 0, 0 115 | 116 | except socket.timeout: 117 | self._gcm_send_heartbeat() 118 | except Exception: 119 | # maybe the socket was closed because we timed out in between calls or 120 | # the connection was interrupted. We close the socket and try to reopen. 121 | try: 122 | self.sock.close() 123 | except: 124 | pass 125 | self.sock = None 126 | 127 | if retry: 128 | return self.receive_verification_from_gcm(False) 129 | else: 130 | raise 131 | 132 | try: 133 | d = json.loads(verification_data) 134 | return d 135 | except Exception as e: 136 | raise_from(GcmException("No verification_code received"), None) 137 | 138 | def _establish_connection(self): 139 | if not self.sock: 140 | self.sock = ssl.wrap_socket(socket.socket(socket.AF_INET, socket.SOCK_STREAM)) 141 | self.sock.connect(("mtalk.google.com", 5228)) 142 | self.sock.setblocking(False) 143 | 144 | self._gcm_send_login(self.android_id, self.security_token) 145 | version = self._rcv_exact(1) 146 | 147 | self.counter = 0 148 | 149 | def _rcv_exact(self, num_bytes): 150 | buf = b'' 151 | while len(buf) < num_bytes: 152 | ready = select.select([self.sock], [], [], 0.2) 153 | if ready[0]: 154 | buf += self.sock.recv(num_bytes - len(buf)) 155 | else: 156 | raise socket.timeout 157 | 158 | return buf 159 | 160 | def _gcm_send_heartbeat(self): 161 | ping = mcs_pb2.HeartbeatAck() 162 | ping.last_stream_id_received = self.counter 163 | ping = ping.SerializeToString() 164 | self.sock.send(struct.pack('B', 0) + varint.encode(len(ping)) + ping) 165 | 166 | def _gcm_send_login(self, android_id, security_token): 167 | lr = mcs_pb2.LoginRequest() 168 | lr.auth_service = 2 169 | lr.auth_token = str(security_token) 170 | lr.id = "android-11" 171 | lr.domain = "mcs.android.com" 172 | lr.device_id = "android-%0.2X" % android_id 173 | lr.resource = str(android_id) 174 | lr.user = str(android_id) 175 | lr.account_id = android_id 176 | 177 | data = lr.SerializeToString() 178 | self.sock.sendall(struct.pack('BB', 41, 2) + varint.encode(len(data)) + data) 179 | 180 | -------------------------------------------------------------------------------- /src/jodel_api/protos/mcs.proto: -------------------------------------------------------------------------------- 1 | // Derived from mcs.proto in chromium source code. Original license text below. 2 | 3 | // Copyright 2013 The Chromium Authors. All rights reserved. 4 | // Use of this source code is governed by a BSD-style license that can be 5 | // found in the LICENSE file. 6 | // 7 | // MCS protocol for communication between Chrome client and Mobile Connection 8 | // Server . 9 | 10 | option java_package = "org.microg.gms.gcm.mcs"; 11 | 12 | /* 13 | Common fields/comments: 14 | 15 | stream_id: no longer sent by server, each side keeps a counter 16 | last_stream_id_received: sent only if a packet was received since last time 17 | a last_stream was sent 18 | status: new bitmask including the 'idle' as bit 0. 19 | 20 | */ 21 | 22 | /** 23 | TAG: 0 24 | */ 25 | message HeartbeatPing { 26 | optional int32 stream_id = 1; 27 | optional int32 last_stream_id_received = 2; 28 | optional int64 status = 3; 29 | } 30 | 31 | /** 32 | TAG: 1 33 | */ 34 | message HeartbeatAck { 35 | optional int32 stream_id = 1; 36 | optional int32 last_stream_id_received = 2; 37 | optional int64 status = 3; 38 | } 39 | 40 | message ErrorInfo { 41 | required int32 code = 1; 42 | optional string message = 2; 43 | optional string type = 3; 44 | optional Extension extension = 4; 45 | } 46 | 47 | // MobileSettings class. 48 | // "u:f", "u:b", "u:s" - multi user devices reporting foreground, background 49 | // and stopped users. 50 | // hbping: heatbeat ping interval 51 | // rmq2v: include explicit stream IDs 52 | 53 | message Setting { 54 | required string name = 1; 55 | required string value = 2; 56 | } 57 | 58 | message HeartbeatStat { 59 | required string ip = 1; 60 | required bool timeout = 2; 61 | required int32 interval_ms = 3; 62 | } 63 | 64 | message HeartbeatConfig { 65 | optional bool upload_stat = 1; 66 | optional string ip = 2; 67 | optional int32 interval_ms = 3; 68 | } 69 | 70 | /** 71 | TAG: 2 72 | */ 73 | message LoginRequest { 74 | enum AuthService { 75 | ANDROID_ID = 2; 76 | } 77 | required string id = 1; // Must be present ( proto required ), may be empty 78 | // string. 79 | // mcs.android.com. 80 | required string domain = 2; 81 | // Decimal android ID 82 | required string user = 3; 83 | 84 | required string resource = 4; 85 | 86 | // Secret 87 | required string auth_token = 5; 88 | 89 | // Format is: android-HEX_DEVICE_ID 90 | // The user is the decimal value. 91 | optional string device_id = 6; 92 | 93 | // RMQ1 - no longer used 94 | optional int64 last_rmq_id = 7; 95 | 96 | repeated Setting setting = 8; 97 | optional int32 compress = 9; 98 | repeated string received_persistent_id = 10; 99 | 100 | // Replaced by "rmq2v" setting 101 | optional bool include_stream_ids = 11; 102 | 103 | optional bool adaptive_heartbeat = 12; 104 | optional HeartbeatStat heartbeat_stat = 13; 105 | // Must be true. 106 | optional bool use_rmq2 = 14; 107 | optional int64 account_id = 15; 108 | 109 | // ANDROID_ID = 2 110 | optional AuthService auth_service = 16; 111 | 112 | optional int32 network_type = 17; 113 | optional int64 status = 18; 114 | } 115 | 116 | /** 117 | * TAG: 3 118 | */ 119 | message LoginResponse { 120 | required string id = 1; 121 | // Not used. 122 | optional string jid = 2; 123 | // Null if login was ok. 124 | optional ErrorInfo error = 3; 125 | repeated Setting setting = 4; 126 | optional int32 stream_id = 5; 127 | // Should be "1" 128 | optional int32 last_stream_id_received = 6; 129 | optional HeartbeatConfig heartbeat_config = 7; 130 | // used by the client to synchronize with the server timestamp. 131 | optional int64 server_timestamp = 8; 132 | } 133 | 134 | message StreamErrorStanza { 135 | required string type = 1; 136 | optional string text = 2; 137 | } 138 | 139 | /** 140 | * TAG: 4 141 | */ 142 | message Close { 143 | } 144 | 145 | message Extension { 146 | // 12: SelectiveAck 147 | // 13: StreamAck 148 | required int32 id = 1; 149 | required bytes data = 2; 150 | } 151 | 152 | /** 153 | * TAG: 7 154 | * IqRequest must contain a single extension. IqResponse may contain 0 or 1 155 | * extensions. 156 | */ 157 | message IqStanza { 158 | enum IqType { 159 | GET = 0; 160 | SET = 1; 161 | RESULT = 2; 162 | IQ_ERROR = 3; 163 | } 164 | 165 | optional int64 rmq_id = 1; 166 | required IqType type = 2; 167 | required string id = 3; 168 | optional string from = 4; 169 | optional string to = 5; 170 | optional ErrorInfo error = 6; 171 | 172 | // Only field used in the 38+ protocol (besides common last_stream_id_received, status, rmq_id) 173 | optional Extension extension = 7; 174 | 175 | optional string persistent_id = 8; 176 | optional int32 stream_id = 9; 177 | optional int32 last_stream_id_received = 10; 178 | optional int64 account_id = 11; 179 | optional int64 status = 12; 180 | } 181 | 182 | message AppData { 183 | required string key = 1; 184 | required string value = 2; 185 | } 186 | 187 | /** 188 | * TAG: 8 189 | */ 190 | message DataMessageStanza { 191 | // Not used. 192 | optional int64 rmq_id = 1; 193 | 194 | // This is the message ID, set by client, DMP.9 (message_id) 195 | optional string id = 2; 196 | 197 | // Project ID of the sender, DMP.1 198 | required string from = 3; 199 | 200 | // Part of DMRequest - also the key in DataMessageProto. 201 | optional string to = 4; 202 | 203 | // Package name. DMP.2 204 | required string category = 5; 205 | 206 | // The collapsed key, DMP.3 207 | optional string token = 6; 208 | 209 | // User data + GOOGLE. prefixed special entries, DMP.4 210 | repeated AppData app_data = 7; 211 | 212 | // Not used. 213 | optional bool from_trusted_server = 8; 214 | 215 | // Part of the ACK protocol, returned in DataMessageResponse on server side. 216 | // It's part of the key of DMP. 217 | optional string persistent_id = 9; 218 | 219 | // In-stream ack. Increments on each message sent - a bit redundant 220 | // Not used in DMP/DMR. 221 | optional int32 stream_id = 10; 222 | optional int32 last_stream_id_received = 11; 223 | 224 | // Not used. 225 | optional string permission = 12; 226 | 227 | // Sent by the device shortly after registration. 228 | optional string reg_id = 13; 229 | 230 | // Not used. 231 | optional string pkg_signature = 14; 232 | // Not used. 233 | optional string client_id = 15; 234 | 235 | // serial number of the target user, DMP.8 236 | // It is the 'serial number' according to user manager. 237 | optional int64 device_user_id = 16; 238 | 239 | // Time to live, in seconds. 240 | optional int32 ttl = 17; 241 | // Timestamp ( according to client ) when message was sent by app, in seconds 242 | optional int64 sent = 18; 243 | 244 | // How long has the message been queued before the flush, in seconds. 245 | // This is needed to account for the time difference between server and 246 | // client: server should adjust 'sent' based on his 'receive' time. 247 | optional int32 queued = 19; 248 | 249 | optional int64 status = 20; 250 | 251 | optional bytes raw_data = 21; 252 | 253 | optional int32 delay = 22; 254 | } 255 | 256 | /** 257 | Included in IQ with ID 13, sent from client or server after 10 unconfirmed 258 | messages. 259 | */ 260 | message StreamAck { 261 | // No last_streamid_received required. This is included within an IqStanza, 262 | // which includes the last_stream_id_received. 263 | } 264 | 265 | /** 266 | Included in IQ sent after LoginResponse from server with ID 12. 267 | */ 268 | message SelectiveAck { 269 | repeated string id = 1; 270 | } 271 | 272 | message BindAccountRequest { 273 | optional string packetid = 1; 274 | optional string domain = 2; 275 | optional string user = 3; 276 | optional string resource = 4; 277 | optional int64 accountid = 9; 278 | optional string token = 5; 279 | } 280 | 281 | message BindAccountResponse { 282 | optional string packetid = 1; 283 | optional string jid = 2; 284 | optional int32 laststreamid = 5; 285 | optional int32 streamid = 4; 286 | optional ErrorInfo error = 3; 287 | } 288 | -------------------------------------------------------------------------------- /src/jodel_api/protos/checkin.proto: -------------------------------------------------------------------------------- 1 | option java_package = "org.microg.gms.checkin"; 2 | 3 | option java_outer_classname = "CheckinProto"; 4 | 5 | // Sample data, if provided, is fished from a Nexus 7 (2013) / flo running Android 5.0 6 | message CheckinRequest { 7 | // unused 8 | optional string imei = 1; 9 | 10 | // Gservices["android_id"] or 0 on first-checkin 11 | optional int64 androidId = 2; 12 | 13 | // Gservices["digest"] or "" 14 | optional string digest = 3; 15 | 16 | required Checkin checkin = 4; 17 | message Checkin { 18 | // empty Build on pre-checkin 19 | required Build build = 1; 20 | message Build { 21 | // Build.FINGERPRINT 22 | // eg. google/razor/flo:5.0.1/LRX22C/1602158:user/release-keys 23 | optional string fingerprint = 1; 24 | 25 | // Build.HARDWARE 26 | // eg. flo 27 | optional string hardware = 2; 28 | 29 | // Build.BRAND 30 | // eg. google 31 | optional string brand = 3; 32 | 33 | // Build.getRadioVersion() 34 | optional string radio = 4; 35 | 36 | // Build.BOOTLOADER 37 | // eg. FLO-04.04 38 | optional string bootloader = 5; 39 | 40 | // GoogleSettingsContract.Partner["client_id"] 41 | // eg. android-google 42 | optional string clientId = 6; 43 | 44 | // Build.TIME / 1000L 45 | // eg. 1416533192 46 | optional int64 time = 7; 47 | 48 | // PackageInfo.versionCode 49 | // eg. 6188736 50 | optional int32 packageVersionCode = 8; 51 | 52 | // Build.DEVICE 53 | // eg. flo 54 | optional string device = 9; 55 | 56 | // Build.VERSION.SDK_INT 57 | // eg. 21 58 | optional int32 sdkVersion = 10; 59 | 60 | // Build.MODEL 61 | // eg. Nexus 7 62 | optional string model = 11; 63 | 64 | // Build.MANUFACTURER 65 | // eg. asus 66 | optional string manufacturer = 12; 67 | 68 | // Build.PRODUCT 69 | // eg. razor 70 | optional string product = 13; 71 | 72 | // fileExists("/system/recovery-from-boot.p") 73 | // eg. false 74 | optional bool otaInstalled = 14; 75 | } 76 | 77 | // last checkin ms or 0 if first checkin 78 | // eg. 0 79 | optional int64 lastCheckinMs = 2; 80 | 81 | // eg. ("event_log_start",~,1424612602652) on first checkin 82 | repeated Event event = 3; 83 | message Event { 84 | optional string tag = 1; 85 | optional string value = 2; 86 | optional int64 timeMs = 3; 87 | } 88 | 89 | // unknown, n/a on first checkin 90 | repeated Statistic stat = 4; 91 | message Statistic { 92 | required string tag = 1; 93 | optional int32 count = 2; 94 | optional float sum = 3; 95 | } 96 | 97 | // unused 98 | repeated string requestedGroup = 5; 99 | 100 | // TelephonyManager.getNetworkOperator != null|empty 101 | optional string cellOperator = 6; 102 | 103 | // TelephonyManager.getSimOperator != null|empty 104 | optional string simOperator = 7; 105 | 106 | // "WIFI::" | ("mobile" | "notmobile" | "unknown") + "-" + ("roaming" | "notroaming" | "unknown") 107 | optional string roaming = 8; 108 | 109 | // UserHandle.myUserId 110 | // eg. 0 111 | optional int32 userNumber = 9; 112 | } 113 | 114 | // unused 115 | optional string desiredBuild = 5; 116 | 117 | // Locale.toString 118 | optional string locale = 6; 119 | 120 | // GoogleSettingsContract.Partner["logging_id2"] (choosen randomly on first checkin) 121 | // eg. 12561488293572742346 122 | optional int64 loggingId = 7; 123 | 124 | // unused 125 | optional string marketCheckin = 8; 126 | 127 | // NetworkInfo.getExtraInfo, WifiInfo.getMacAddress (12 hex-digits) 128 | // eg. d850e6abcdef 129 | repeated string macAddress = 9; 130 | 131 | // TelephonyManager.getDeviceId (14 hex-digits), not set on tablets 132 | optional string meid = 10; 133 | 134 | // "[]" followed by "", empty string on first checkin 135 | repeated string accountCookie = 11; 136 | 137 | // TimeZone.getId 138 | // eg. GMT 139 | optional string timeZone = 12; 140 | 141 | // security token as given on first checkin, not set on first checkin 142 | optional fixed64 securityToken = 13; 143 | 144 | // use 3 145 | optional int32 version = 14; 146 | 147 | // SHA-1 of each in /system/etc/security/otacerts.zip or "--IOException--" or "--no-output--" 148 | // eg. dKXTm1QH9QShGQwBM/4rg6/lCNQ= 149 | repeated string otaCert = 15; 150 | 151 | // Build.SERIAL != "unknown" 152 | // eg. 07d90b18 153 | optional string serial = 16; 154 | 155 | // TelephonyManager.getDeviceId (8 hex-digits), not set on tablets 156 | optional string esn = 17; 157 | 158 | optional DeviceConfig deviceConfiguration = 18; 159 | message DeviceConfig { 160 | // ConfigurationInfo.reqTouchScreen 161 | // eg. 3 162 | optional int32 touchScreen = 1; 163 | 164 | // ConfigurationInfo.reqKeyboardType 165 | // eg. 1 166 | optional int32 keyboardType = 2; 167 | 168 | // ConfigurationInfo.reqNavigation 169 | // eg. 1 170 | optional int32 navigation = 3; 171 | // ConfigurationInfo.screenLayout 172 | // eg. 3 173 | optional int32 screenLayout = 4; 174 | 175 | // ConfigurationInfo.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD 176 | // eg. 0 177 | optional bool hasHardKeyboard = 5; 178 | 179 | // ConfigurationInfo.reqInputFeatures & ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV 180 | // eg. 0 181 | optional bool hasFiveWayNavigation = 6; 182 | 183 | // DisplayMetrics.densityDpi 184 | // eg. 320 185 | optional int32 densityDpi = 7; 186 | 187 | // ConfigurationInfo.reqGlEsVersion 188 | // eg. 196608 189 | optional int32 glEsVersion = 8; 190 | 191 | // PackageManager.getSystemSharedLibraryNames 192 | // eg. "android.test.runner", "com.android.future.usb.accessory", "com.android.location.provider", 193 | // "com.android.media.remotedisplay", "com.android.mediadrm.signer", "com.google.android.maps", 194 | // "com.google.android.media.effects", "com.google.widevine.software.drm", "javax.obex" 195 | repeated string sharedLibrary = 9; 196 | 197 | // PackageManager.getSystemAvailableFeatures 198 | // eg. android.hardware.[...] 199 | repeated string availableFeature = 10; 200 | 201 | // Build.CPU_ABI and Build.CPU_ABI2 != "unknown" 202 | // eg. "armeabi-v7a", "armeabi" 203 | repeated string nativePlatform = 11; 204 | 205 | // DisplayMetrics.widthPixels 206 | // eg. 1200 207 | optional int32 widthPixels = 12; 208 | 209 | // DisplayMetrics.heightPixels 210 | // eg. 1824 211 | optional int32 heightPixels = 13; 212 | 213 | // Context.getAssets.getLocales 214 | // eg. [...], "en-US", [...] 215 | repeated string locale = 14; 216 | 217 | // GLES10.glGetString(GLES10.GL_EXTENSIONS) 218 | // eg. "GL_AMD_compressed_ATC_texture", [...] 219 | repeated string glExtension = 15; 220 | 221 | // unused 222 | optional int32 deviceClass = 16; 223 | // unused 224 | optional int32 maxApkDownloadSizeMb = 17; 225 | } 226 | 227 | // "ethernet" or "wifi" 228 | repeated string macAddressType = 19; 229 | 230 | // unknown, use 0 on pre- and first-checkin, and 1 for later checkins 231 | // also present on pre-checkin 232 | required int32 fragment = 20; 233 | 234 | // unknown 235 | optional string userName = 21; 236 | 237 | // UserManager.getUserSerialNumber 238 | // eg. 0 239 | optional int32 userSerialNumber = 22; 240 | } 241 | 242 | message CheckinResponse { 243 | optional bool statsOk = 1; 244 | repeated Intent intent = 2; 245 | message Intent { 246 | optional string action = 1; 247 | optional string dataUri = 2; 248 | optional string mimeType = 3; 249 | optional string javaClass = 4; 250 | repeated Extra extra = 5; 251 | message Extra { 252 | optional string name = 6; 253 | optional string value = 7; 254 | } 255 | } 256 | optional int64 timeMs = 3; 257 | optional string digest = 4; 258 | repeated GservicesSetting setting = 5; 259 | message GservicesSetting { 260 | optional bytes name = 1; 261 | optional bytes value = 2; 262 | } 263 | optional bool marketOk = 6; 264 | optional fixed64 androidId = 7; 265 | optional fixed64 securityToken = 8; 266 | optional bool settingsDiff = 9; 267 | repeated string deleteSetting = 10; 268 | optional string versionInfo = 11; 269 | optional string deviceDataVersionInfo = 12; 270 | } 271 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | Jodel API 2 | ========= 3 | 4 | |Build Status| |Coverage Status| |Health| |Python Versions| |PyPI Version| |License| 5 | 6 | Inofficial interface to the private API of the Jodel App. Not affiliated 7 | with *The Jodel Venture GmbH*. 8 | 9 | Installation 10 | ------------ 11 | 12 | Using pip: 13 | 14 | .. code:: 15 | 16 | pip install jodel_api 17 | 18 | or using setup.py: 19 | 20 | .. code:: 21 | 22 | git clone https://github.com/nborrmann/jodel_api.git 23 | cd jodel_api 24 | python setup.py install 25 | 26 | 27 | Usage 28 | ----- 29 | 30 | Account Creation 31 | ~~~~~~~~~~~~~~~~ 32 | 33 | Calling the bare constructor creates a new account: 34 | 35 | .. code:: python 36 | 37 | >>> import jodel_api 38 | >>> lat, lng, city = 48.148434, 11.567867, "Munich" 39 | >>> j = jodel_api.JodelAccount(lat=lat, lng=lng, city=city) 40 | Creating new account. 41 | 42 | ``get_account_data()`` returns all data associated with this account 43 | (censored by me): 44 | 45 | .. code:: python 46 | 47 | >>> j.get_account_data() 48 | {'access_token': 'xxx', 'expiration_date': 1472660000, 'refresh_token': 'xxx', 'distinct_id': 'xxx', 'device_uid': 'xxx'} 49 | 50 | Save this data to reuse the account later on, feed it to the 51 | JodelAccount() constructor to reinitiate the account. This constructor 52 | issues one request to update the location of the account. 53 | 54 | .. code:: python 55 | 56 | >>> j = jodel_api.JodelAccount(lat=lat, lng=lng, city=city, access_token='xxx', expiration_date='xxx', 57 | refresh_token='xxx', distinct_id='xxx', device_uid='xxx', is_legacy=True) 58 | (204, '') 59 | 60 | Add ``update_location=False`` to suppress this behaviour. The 61 | constructor will only instantiate an object, without making any remote 62 | calls: 63 | 64 | .. code:: python 65 | 66 | >>> j = jodel_api.JodelAccount(lat=lat, lng=lng, city=city, update_location=False, **account_data) 67 | 68 | After ``expiration_date`` has passed, call ``refresh_access_tokens()`` 69 | to re-authenticate. If ``refresh_access_token`` fails, use 70 | ``refresh_all_tokens`` instead (this is akin to creating a new account, 71 | but preserves the account's data (karma, etc)): 72 | 73 | .. code:: python 74 | 75 | >>> j.refresh_access_token() 76 | (200, {'token_type': 'bearer', 'access_token': 'xxx', 'expires_in': 604800, 'expiration_date': xxx}) 77 | >>> j.refresh_all_tokens() 78 | (200, {'expires_in': 604800, 'access_token': 'xxx', 'token_type': 'bearer', 'returning': True, 79 | 'refresh_token': 'xxx', 'expiration_date': 1472600000, 'distinct_id': 'xxx'}) 80 | 81 | 82 | Account Verification 83 | ~~~~~~~~~~~~~~~~~~~~ 84 | 85 | For some functionality like voting and posting (look out for error 478) 86 | accounts need to be verified. 87 | 88 | With Jodel version ``4.48`` captcha verification has been disabled. 89 | However old accounts will continue to work with version ``4.47``. But if you 90 | ever use an old, verified account with version ``4.48`` it will become 91 | unverified. To this end, use the flag ``is_legacy=True`` in the 92 | constructor when you instantiate an old account (on by default). New 93 | accounts must be created with ``is_legacy=False``. 94 | 95 | In ``4.48`` accounts can only be verified through Google Cloud Messaging. 96 | The steps are as follows: 97 | 98 | 1. Create an Android Account: ``a = jodel_api.AndroidAccount()`` 99 | 2. Request a push token: ``a.get_push_token()`` 100 | 3. Send push token to Jodel Servers: ``j.send_push_token(token)`` 101 | 4. Log into GCM and read push messages (``verification_code``) from 102 | Jodel: ``verification = a.receive_verification_from_gcm()`` 103 | 5. Send the verification code to Jodel to verify the account: 104 | ``a.verify_push(server_time, verification_code)`` 105 | 106 | In ``jodel_api`` this is implemented as follows: 107 | 108 | .. code:: python 109 | 110 | a = jodel_api.AndroidAccount() 111 | j.verify(a) 112 | 113 | Tip: If the call is successful, save the account credentials and reuse 114 | them later (if you get ``REGISTRATION_INVALID`` retry with another 115 | account): 116 | 117 | .. code:: python 118 | 119 | account_id, security_token = a.android_id, a.security_token 120 | a2 = jodel_api.AndroidAccount(account_id, security_token) 121 | 122 | 123 | API calls 124 | ~~~~~~~~~ 125 | 126 | All remote API calls return a tuple of HTTP status\_code and the 127 | response (if possible a dict, parsed from the API response), but might 128 | also be a string (error message). 129 | 130 | The following API calls are supported (presented without their 131 | respective responses): 132 | 133 | 134 | .. code:: python 135 | 136 | # API methods for reading posts: 137 | >>> j.get_posts_recent(skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None) 138 | >>> j.get_posts_popular(skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None) 139 | >>> j.get_posts_discussed(skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None) 140 | >>> j.get_pictures_recent(skip=0, limit=60, after=None) 141 | >>> j.get_pictures_popular(skip=0, limit=60, after=None) 142 | >>> j.get_pictures_discussed(skip=0, limit=60, after=None) 143 | >>> j.get_my_pinned_posts(skip=0, limit=60, after=None) 144 | >>> j.get_my_replied_posts(skip=0, limit=60, after=None) 145 | >>> j.get_my_voted_posts(skip=0, limit=60, after=None) 146 | >>> j.post_search(message, skip=0, limit=60) 147 | 148 | # API methods for interacting with single posts: 149 | >>> j.create_post(message=None, imgpath=None, b64img=None, color=None, ancestor=None, channel="") 150 | >>> j.get_post_details(post_id) # This endpoint has been deprecated. Use get_post_details_v3. 151 | >>> # This api endpoint implements paging and returns at most 50 replies, 152 | >>> # use the skip parameter to page through the thread: 153 | >>> j.get_post_details_v3(post_id, skip=0) 154 | >>> j.upvote(post_id) 155 | >>> j.downvote(post_id) 156 | >>> j.give_thanks(post_id) 157 | >>> j.get_share_url(post_id) 158 | >>> j.pin(post_id) 159 | >>> j.unpin(post_id) 160 | >>> j.enable_notifications(post_id) 161 | >>> j.disable_notifications(post_id) 162 | >>> j.delete_post(post_id) # Only works on your own posts ಠ_ಠ 163 | 164 | # API methods for interacting with sticky posts: 165 | >>> j.upvote_sticky_post(post_id) 166 | >>> j.downvote_sticky_post(post_id) 167 | >>> j.dismiss_sticky_post(post_id) 168 | 169 | # API methods for interacting with notifications: 170 | >>> j.get_notifications() 171 | >>> j.get_notifications_new() 172 | >>> j.notification_read(post_id=None, notification_id=None) 173 | 174 | # API methods for interacting with channels: 175 | >>> j.get_recommended_channels() 176 | >>> j.get_channel_meta(channel) 177 | >>> j.follow_channel(channel) 178 | >>> j.unfollow_channel(channel) 179 | 180 | # API methods for interacting with your user profile: 181 | >>> j.set_location(lat, lng, city, country=None, name=None) # country and name appear to have no effect 182 | >>> j.set_user_profile(user_type=None, gender=None, age=None) 183 | >>> j.get_user_config() 184 | >>> j.get_karma() 185 | >>> j.get_captcha() 186 | >>> j.submit_captcha(key, answer) 187 | 188 | 189 | The parameters ``skip``, 190 | ``limit`` and ``after`` implement paging. While ``skip`` and ``limit`` 191 | are integers, ``after`` is a ``post_id`` parameter and will return all 192 | jodels that follow that one. The former two paramters seem to be 193 | deprecated in favor of the latter, however ``after`` doesn't work 194 | on all ``/mine/`` endpoints (ie. ``mine=True`` or ``get_my_x_posts``). 195 | 196 | The arguments ``mine`` (boolean), ``hashtag``, ``channel`` (both strings) 197 | are exclusive. If ``mine`` evaluates to ``true``, the other two arguments 198 | are discarded, if ``hashtag`` evaluates ``true`` , ``channel`` is 199 | discarded. 200 | 201 | ``post_search()`` is a new endpoint (as of June 17) that isn't yet 202 | available through the app. It returns all posts from your location 203 | that contain a given string. 204 | 205 | You can pass additional arguments (such as proxies and timeouts) to all 206 | API calls through the ``**xargs`` argument that will be passed to the 207 | ``requests.request()`` function: 208 | 209 | .. code:: python 210 | 211 | >>> j.upvote(post_id, timeout=5, proxies={'https': '127.0.0.1:5000'}) 212 | 213 | For unimplemented endpoints, check `issue #22 214 | `_. 215 | 216 | 217 | Error Codes 218 | ~~~~~~~~~~~ 219 | 220 | - **401 "Unauthorized"**: Your ``access_token`` is invalid. Either 221 | you messed up, or it is outdated. You need to call 222 | ``refresh_access_token()`` or ``refresh_all_token()`` (check the 223 | above section on account creation). 224 | - **401 "Action not allowed"**: You are using a ``4.48`` account 225 | with ``is_legacy=True``, but ``4.48`` accounts are not allowed 226 | to downgrade. 227 | - **403 "Access Denied"**: Your IP is banned accross endpoints, 228 | just read-only endpoints still work. Effective for 24 hours. 229 | - **429 "Too Many Requests"**: Your IP is rate-limited. Applies only 230 | to one specific endpoint. 231 | - **477 "Signed Request Expected"**: This library should handle request 232 | signing. Make sure to upgrade to the latest version of ``jodel_api``, 233 | as the signing key changes every few weeks. 234 | - **478 "Account not verified"**: Verify the account through GCM. 235 | - **502 "Bad Gateway"**: Something went wrong server-side. This happens 236 | pretty randomly. ``jodel_api`` automatically retries two times when 237 | it sees this error. If you encounter this status, the jodel servers 238 | are probably having issues. Try again later. 239 | 240 | Rate-Limits 241 | ~~~~~~~~~~~ 242 | 243 | The Jodel API appears to have the following (IP-based) rate-limits 244 | 245 | - max of 200 new account registrations from one IP per half hour 246 | - max of 200 votes per minute 247 | - max of 100 captcha requests per minute 248 | 249 | They also hand out 403 bans if you overdo it. 250 | 251 | Tests 252 | ----- 253 | 254 | Nearly all tests in ``jodel_api_test.py`` are integration tests, which 255 | actually hit the Jodel servers. These can fail for any number of reasons 256 | (eg. connectivity issues), which does not necessarily imply there is 257 | something wrong with this library. As this library tries to make few 258 | assumptions about the content of the json responses they test mostly for 259 | status codes, not the contents of the responses (ie. they test whether 260 | the API endpoints are still valid). 261 | 262 | - For the tests in ``class TestUnverifiedAccount`` a new account is 263 | created on every run and they test GCM verification, posting and 264 | read-only functions 265 | - Tests in ``class TestLegacyVerifiedAccount`` need an already verified 266 | legacy account and test if it still works. 267 | To run these tests you need to verify an account by 268 | solving the captcha and save its ``device_uid`` in the 269 | environment variable ``JODEL_ACCOUNT_LEGACY``. Run 270 | ``j.get_account_data()['device_uid']`` to get the value. 271 | 272 | Linux: 273 | 274 | :: 275 | 276 | export JODEL_ACCOUNT_LEGACY=a8aa02[...]dba 277 | 278 | Windows (you need to restart the cmd/shell for this to take effect, 279 | or set it through gui): 280 | 281 | :: 282 | 283 | setx JODEL_ACCOUNT_LEGACY a8aa02[...]dba 284 | 285 | If this variable is not present, these tests will be skipped. 286 | 287 | Clone the directory, install the library and run the tests with 288 | 289 | .. code:: python 290 | 291 | python setup.py test 292 | 293 | .. |Build Status| image:: https://travis-ci.org/nborrmann/jodel_api.svg?branch=master 294 | :target: https://travis-ci.org/nborrmann/jodel_api 295 | .. |Coverage Status| image:: https://img.shields.io/codecov/c/github/nborrmann/jodel_api.svg 296 | :target: https://codecov.io/gh/nborrmann/jodel_api 297 | .. |Health| image:: https://landscape.io/github/nborrmann/jodel_api/master/landscape.svg?style=flat 298 | :target: https://landscape.io/github/nborrmann/jodel_api/master 299 | .. |Python Versions| image:: https://img.shields.io/pypi/pyversions/jodel_api.svg 300 | :target: https://pypi.python.org/pypi/jodel_api/ 301 | .. |PyPI Version| image:: https://img.shields.io/pypi/v/jodel_api.svg 302 | :target: https://pypi.python.org/pypi/jodel_api/ 303 | .. |License| image:: https://img.shields.io/pypi/l/jodel_api.svg 304 | :target: https://pypi.python.org/pypi/jodel_api/ 305 | -------------------------------------------------------------------------------- /test/test_jodel_api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import (absolute_import, print_function, unicode_literals) 4 | import jodel_api 5 | from random import uniform, choice 6 | import datetime 7 | import base64 8 | import pytest 9 | from string import ascii_lowercase 10 | from mock import MagicMock, patch 11 | import builtins 12 | import requests 13 | import os 14 | from flaky import flaky 15 | import time 16 | 17 | lat, lng, city = 49.021785, 12.103129, "Regensburg" 18 | test_channel = "WasGehtHeute?" 19 | 20 | def delay_rerun(*args): 21 | time.sleep(3) 22 | return True 23 | 24 | 25 | @flaky(max_runs=2, rerun_filter=delay_rerun) 26 | class TestUnverifiedAccount: 27 | 28 | @classmethod 29 | def setup_class(self): 30 | self.j = jodel_api.JodelAccount(lat + uniform(-0.01, 0.01), lng + uniform(-0.01, 0.01), city) 31 | assert isinstance(self.j, jodel_api.JodelAccount) 32 | 33 | r = self.j.get_posts_discussed() 34 | assert r[0] == 200 35 | assert "posts" in r[1] and "post_id" in r[1]["posts"][0] 36 | self.pid = r[1]['posts'][0]['post_id'] 37 | self.pid1 = r[1]['posts'][0]['post_id'] 38 | self.pid2 = r[1]['posts'][1]['post_id'] 39 | assert self.j.follow_channel(test_channel)[0] == 204 40 | 41 | assert self.j.get_account_data()['is_legacy'] == False 42 | 43 | def __repr__(self): 44 | return "TestUnverifiedAccount <%s, %s>" % (self.j.get_account_data()['device_uid'], self.pid) 45 | 46 | def test_reinitalize(self): 47 | acc = self.j.get_account_data() 48 | with pytest.raises(Exception) as excinfo: 49 | j2 = jodel_api.JodelAccount(lat="a", lng="b", city=13, update_location=True, **acc) 50 | 51 | assert "Error updating location" in str(excinfo.value) 52 | 53 | def test_refresh_access_token(self): 54 | r = self.j.refresh_access_token() 55 | assert r[0] == 200 56 | assert set(r[1].keys()) == set(["expiration_date", "token_type", "expires_in", "access_token"]) 57 | 58 | def test_set_location(self): 59 | r = self.j.set_location(lat + uniform(-0.01, 0.01), lng + uniform(-0.01, 0.01), city) 60 | assert r[0] == 204 61 | 62 | def test_read_posts_recent(self): 63 | r = self.j.get_posts_recent() 64 | assert r[0] == 200 65 | 66 | def test_get_my_posts(self): 67 | assert self.j.get_my_voted_posts()[0] == 200 68 | assert self.j.get_my_replied_posts()[0] == 200 69 | assert self.j.get_my_pinned_posts()[0] == 200 70 | 71 | def test_popular_after(self): 72 | r = self.j.get_posts_popular() 73 | assert r[0] == 200 74 | assert 'posts' in r[1] 75 | 76 | if not r[1]['posts']: 77 | pytest.skip("posts_popular() returned no posts") 78 | 79 | print("after:", r[1]['posts'][10]) 80 | r2 = self.j.get_posts_popular(after=r[1]['posts'][10]['post_id']) 81 | assert r2[0] == 200 82 | assert 'posts' in r2[1] 83 | if not r2[1]['posts']: 84 | pytest.skip("posts_popular(after=) returned no posts") 85 | 86 | # did the after parameter work? 87 | r2_vote_counts = [post["vote_count"] for post in r2[1]["posts"]] 88 | assert all([r[1]['posts'][10]["vote_count"] >= t for t in r2_vote_counts[1:]]) 89 | 90 | def test_channel_after(self): 91 | r = self.j.get_posts_discussed(channel=test_channel) 92 | assert r[0] == 200 93 | assert 'posts' in r[1] 94 | 95 | if not r[1]['posts'] or len(r[1]['posts']) < 11: 96 | pytest.skip("posts_discussed(channel=) returned no posts") 97 | 98 | print("after:", r[1]['posts'][10]) 99 | r2 = self.j.get_posts_discussed(channel=test_channel, after=r[1]['posts'][10]['post_id']) 100 | assert r2[0] == 200 101 | assert 'posts' in r2[1] 102 | if not r2[1]['posts']: 103 | pytest.skip("posts_discussed(channel=, after=) returned no posts") 104 | 105 | # did the after parameter work? 106 | r2_child_counts = [post.get("child_count", 0) for post in r2[1]["posts"]] 107 | assert all([r[1]['posts'][10]["child_count"] + 1 >= t for t in r2_child_counts[1:]]) 108 | 109 | def test_get_posts_channel(self): 110 | r = self.j.get_posts_recent(channel=test_channel) 111 | assert r[0] == 200 112 | assert "posts" in r[1] 113 | 114 | def test_get_pictures(self): 115 | r = self.j.get_pictures_recent() 116 | assert r[0] == 200 117 | assert "posts" in r[1] 118 | 119 | r = self.j.get_pictures_popular() 120 | assert r[0] == 200 121 | assert "posts" in r[1] 122 | 123 | r = self.j.get_pictures_discussed() 124 | assert r[0] == 200 125 | assert "posts" in r[1] 126 | 127 | def test_get_channels(self): 128 | r = self.j.get_recommended_channels() 129 | assert "local" in r[1] 130 | assert r[0] == 200 131 | 132 | channel = r[1]["local"][0]["channel"] 133 | assert self.j.get_channel_meta(channel)[0] == 200 134 | 135 | def test_set_get_config(self): 136 | user_type = choice(["high_school", "high_school_graduate", "student", "apprentice", "employee", "other"]) 137 | r = self.j.set_user_profile(user_type=user_type, gender=choice(['m', 'f'])) 138 | assert r[0] == 204 139 | 140 | r = self.j.get_user_config() 141 | print(r) 142 | assert r[0] == 200 143 | assert "verified" in r[1] 144 | assert r[1]["user_type"] == user_type 145 | 146 | assert self.j.get_karma()[0] == 200 147 | 148 | def set_user_profile(self, user_type=None, gender=None, age=None, **kwargs): 149 | allowed_user_types = ["high_school", "high_school_graduate", "student", "apprentice", "employee", "other"] 150 | if user_type not in allowed_user_types: 151 | raise ValueError("user_type must be one of {}.".format(allowed_user_types)) 152 | 153 | if gender not in ["m", "f"]: 154 | raise ValueError("gender must be either m or f.") 155 | 156 | return self._send_request("PUT", "/v3/user/profile", payload={"user_type": user_type, "gender": gender, "age": age}, **kwargs) 157 | 158 | def test_notifications(self): 159 | assert self.j.get_notifications_new()[0] == 200 160 | assert self.j.get_notifications()[0] == 200 161 | 162 | def test_post_details(self): 163 | r = self.j.get_post_details(self.pid) 164 | assert r[0] == 200 165 | #assert len(r[1]["children"]) == r[1]["child_count"] 166 | 167 | def test_post_details_v3(self): 168 | assert self.j.get_post_details_v3(self.pid)[0] == 200 169 | 170 | def test_share_url(self): 171 | assert self.j.get_share_url(self.pid)[0] == 200 172 | 173 | def test_pin(self): 174 | assert self.j.pin(self.pid)[0] == 200 175 | assert self.j.unpin(self.pid)[0] == 200 176 | 177 | def test_switch_notifications(self): 178 | r = self.j.enable_notifications(self.pid) 179 | assert r[0] == 200 180 | assert r[1]["notifications_enabled"] == True 181 | 182 | r = self.j.disable_notifications(self.pid) 183 | assert r[0] == 200 184 | assert r[1]["notifications_enabled"] == False 185 | 186 | @flaky(max_runs=3, rerun_filter=delay_rerun) 187 | def test_verify(self): 188 | r = self.j.verify() 189 | assert r[0] == 200 190 | 191 | r = self.j.get_user_config() 192 | assert r[0] == 200 193 | assert r[1]['verified'] == True 194 | 195 | def test_vote(self): 196 | assert self.j.upvote(self.pid)[0] == 200 197 | assert self.j.downvote(self.pid)[0] == 200 198 | 199 | def test_post_reply(self): 200 | msg = "This is an automated test message. Location is %f:%f. Time is %s. %s" % \ 201 | (lat, lng, datetime.datetime.now(), "".join(choice(ascii_lowercase) for _ in range(20))) 202 | r = self.j.create_post(msg, ancestor=self.pid1) 203 | print(r) 204 | assert r[0] == 200 205 | assert "post_id" in r[1] 206 | 207 | p = self.j.get_post_details(self.pid1) 208 | assert p[0] == 200 209 | assert "children" in p[1] 210 | print([post["post_id"] for post in p[1]["children"]]) 211 | assert r[1]["post_id"] in [post["post_id"] for post in p[1]["children"]] 212 | my_post = next(post for post in p[1]["children"] if post["post_id"] == r[1]["post_id"]) 213 | assert my_post["message"] == msg 214 | 215 | assert self.j.delete_post(r[1]["post_id"])[0] == 204 216 | 217 | def test_post_channel_img(self): 218 | color = "9EC41C" 219 | msg = "This is an automated test message. Color is #%s. Location is %f:%f. Time is %s. %s" % \ 220 | (color, lat, lng, datetime.datetime.now(), "".join(choice(ascii_lowercase) for _ in range(20))) 221 | with open("test/testimg.png", "rb") as f: 222 | imgdata = base64.b64encode(f.read()).decode("utf-8") + "".join(choice(ascii_lowercase) for _ in range(10)) 223 | 224 | r = self.j.create_post(msg, b64img=imgdata, color=color, channel=test_channel) 225 | print(r) 226 | assert r[0] == 200 227 | assert "post_id" in r[1] 228 | 229 | assert self.j.delete_post(r[1]["post_id"])[0] == 204 230 | 231 | """ 232 | @pytest.mark.skip() 233 | def test_post_channel(self): 234 | color = "9EC41C" 235 | msg = "This is an automated test message to the channel %s. Color is #%s. Location is %f:%f. Time is %s. %s" % \ 236 | (test_channel, color, lat, lng, datetime.datetime.now(), "".join(choice(ascii_lowercase) for _ in range(20))) 237 | 238 | r = self.j.create_post(msg, color=color, channel=test_channel) 239 | print(r) 240 | assert r[0] == 200 241 | assert "post_id" in r[1] 242 | 243 | p = self.j.get_posts_recent(channel=test_channel) 244 | assert p[0] == 200 245 | print([post["post_id"] for post in p[1]["posts"]]) 246 | assert r[1]["post_id"] in [post["post_id"] for post in p[1]["posts"]] 247 | my_post = next(post for post in p[1]["posts"] if post["post_id"] == r[1]["post_id"]) 248 | assert my_post["message"] == msg 249 | 250 | assert self.j.delete_post(r[1]["post_id"])[0] == 204 251 | """ 252 | 253 | @patch('jodel_api.s.request') 254 | def test_bad_gateway_retry(self, requests_func): 255 | requests_func.return_value = MagicMock(status_code=502, text="Bad Gateway") 256 | 257 | r = self.j.enable_notifications(self.pid) 258 | assert r[0] == 502 259 | assert requests_func.call_count == 3 260 | 261 | @patch('jodel_api.s.request') 262 | def test_bad_gateway_no_retry(self, requests_func): 263 | requests_func.return_value = MagicMock(status_code=200, json={'notifications_enabled': True}) 264 | 265 | r = self.j.enable_notifications(self.pid) 266 | assert r[0] == 200 267 | assert requests_func.call_count == 1 268 | 269 | def test_follow_channel(self): 270 | assert self.j.follow_channel(test_channel)[0] == 204 271 | assert self.j.unfollow_channel(test_channel)[0] == 204 272 | 273 | 274 | @pytest.mark.skipif(not os.environ.get("JODEL_ACCOUNT_LEGACY"), reason="requires an account uid as environment variable") 275 | class TestLegacyVerifiedAccount: 276 | 277 | @classmethod 278 | @flaky(max_runs=2, rerun_filter=delay_rerun) 279 | def setup_class(self): 280 | acc = {'device_uid': os.environ.get("JODEL_ACCOUNT_LEGACY")} 281 | self.j = jodel_api.JodelAccount(lat, lng, city, update_location=False, is_legacy=True, **acc) 282 | assert self.j.get_account_data()['is_legacy'] 283 | 284 | assert self.j.set_location(lat, lng, city)[0] == 204 285 | 286 | # get two post_ids for further testing 287 | r = self.j.get_posts_discussed() 288 | assert r[0] == 200 289 | assert "posts" in r[1] and "post_id" in r[1]["posts"][0] 290 | self.pid1 = r[1]['posts'][0]['post_id'] 291 | self.pid2 = r[1]['posts'][1]['post_id'] 292 | print(self.pid1, self.pid2) 293 | 294 | # make sure get_my_pinned() isn't empty 295 | pinned = self.j.get_my_pinned_posts() 296 | assert pinned[0] == 200 297 | if len(pinned[1]["posts"]) < 5: 298 | for post in r[1]["posts"][4:9]: 299 | self.j.pin(post["post_id"]) 300 | 301 | # follow the channel so we can post to it 302 | assert self.j.follow_channel(test_channel)[0] == 204 303 | 304 | def __repr__(self): 305 | return "TestUnverifiedAccount <%s, %s>" % (self.pid1, self.pid2) 306 | 307 | def test_legacy(self): 308 | assert self.j.get_account_data()['is_legacy'] 309 | 310 | @pytest.mark.xfail(reason="after parameter doesn't work with /mine/ endpoints") 311 | def test_my_pin_after(self): 312 | r = self.j.get_my_pinned_posts() 313 | assert r[0] == 200 314 | assert 'posts' in r[1] 315 | 316 | if not r[1]['posts']: 317 | pytest.skip("my_pinned_posts() returned no posts") 318 | 319 | print("after:", r[1]['posts'][3]) 320 | r2 = self.j.get_my_pinned_posts(after=r[1]['posts'][3]['post_id']) 321 | assert r2[0] == 200 322 | assert 'posts' in r2[1] 323 | if not r2[1]['posts']: 324 | pytest.skip("my_pinned_posts(after=) returned no posts") 325 | 326 | # did the after parameter work? 327 | r2_create_times = [post["created_at"] for post in r2[1]["posts"]] 328 | assert all([r[1]['posts'][3]["created_at"] > t for t in r2_create_times]) 329 | 330 | @pytest.mark.xfail(reason="after parameter doesn't work with /mine/ endpoints") 331 | def test_my_voted_after(self): 332 | r = self.j.get_my_voted_posts() 333 | assert r[0] == 200 334 | assert 'posts' in r[1] 335 | 336 | if not r[1]['posts']: 337 | pytest.skip("my_voted_posts() returned no posts") 338 | 339 | print("after:", r[1]['posts'][3]) 340 | r2 = self.j.get_my_voted_posts(after=r[1]['posts'][3]['post_id']) 341 | assert r2[0] == 200 342 | assert 'posts' in r2[1] 343 | if not r2[1]['posts']: 344 | pytest.skip("my_voted_posts(after=) returned no posts") 345 | 346 | # did the after parameter work? 347 | r2_create_times = [post["created_at"] for post in r2[1]["posts"]] 348 | assert all([r[1]['posts'][3]["created_at"] > t for t in r2_create_times]) 349 | 350 | @flaky(max_runs=2, rerun_filter=delay_rerun) 351 | def test_notifications_read(self): 352 | assert self.j.get_notifications_new()[0] == 200 353 | 354 | r = self.j.get_notifications() 355 | print(r) 356 | assert r[0] == 200 357 | assert "notifications" in r[1] 358 | 359 | if not r[1]["notifications"]: 360 | pytest.skip("no notifications returned, cannot mark as read") 361 | 362 | nid = r[1]["notifications"][0]["notification_id"] 363 | assert self.j.notification_read(notification_id=nid)[0] == 204 364 | assert self.j.notification_read(post_id=self.pid1)[0] == 204 365 | 366 | @flaky(max_runs=2, rerun_filter=delay_rerun) 367 | def test_post_message(self): 368 | color = "FF9908" 369 | msg = "This is an automated test message. äöü§$%%&àô. Color is #%s. Location is %f:%f. Time is %s. %s" % \ 370 | (color, lat, lng, datetime.datetime.now(), "".join(choice(ascii_lowercase) for _ in range(20))) 371 | r = self.j.create_post(msg, color=color) 372 | print(r) 373 | assert r[0] == 200 374 | assert "post_id" in r[1] 375 | 376 | p = self.j.get_post_details(r[1]["post_id"]) 377 | assert p[0] == 200 378 | assert p[1]["color"] == color 379 | assert p[1]["message"] == msg 380 | 381 | assert self.j.delete_post(r[1]["post_id"])[0] == 204 382 | 383 | @flaky(max_runs=2, rerun_filter=delay_rerun) 384 | def test_vote(self): 385 | assert self.j.upvote(self.pid1)[0] == 200 386 | assert self.j.downvote(self.pid2)[0] == 200 387 | -------------------------------------------------------------------------------- /src/jodel_api/jodel_api.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from __future__ import (absolute_import, print_function, unicode_literals) 4 | from builtins import input 5 | from future.standard_library import install_aliases 6 | install_aliases() 7 | 8 | import base64 9 | import datetime 10 | from hashlib import sha1 11 | import hmac 12 | import json 13 | import random 14 | import requests 15 | from urllib.parse import urlparse 16 | from jodel_api import gcmhack 17 | import time 18 | 19 | s = requests.Session() 20 | 21 | 22 | class JodelAccount: 23 | post_colors = ['9EC41C', 'FF9908', 'DD5F5F', '8ABDB0', '06A3CB', 'FFBA00'] 24 | 25 | api_url = "https://api.go-tellm.com/api{}" 26 | client_id = '81e8a76e-1e02-4d17-9ba0-8a7020261b26' 27 | secret = 'HtJoqSysGFQXgFqYZRgwbpcFVAzLFSioVKTCwMcL'.encode('ascii') 28 | version = '4.79.1' 29 | secret_legacy = 'hyTBJcvtpDLSgGUWjybbYUNKSSoVvMcfdjtjiQvf'.encode('ascii') 30 | version_legacy = '4.47.0' 31 | 32 | 33 | access_token = None 34 | device_uid = None 35 | 36 | def __init__(self, lat, lng, city, country=None, name=None, update_location=True, 37 | access_token=None, device_uid=None, refresh_token=None, distinct_id=None, expiration_date=None, 38 | is_legacy=True, **kwargs): 39 | self.lat, self.lng, self.location_dict = lat, lng, self._get_location_dict(lat, lng, city, country, name) 40 | 41 | self.is_legacy = is_legacy 42 | if device_uid: 43 | self.device_uid = device_uid 44 | 45 | if access_token and device_uid and refresh_token and distinct_id and expiration_date: 46 | self.expiration_date = expiration_date 47 | self.distinct_id = distinct_id 48 | self.refresh_token = refresh_token 49 | self.access_token = access_token 50 | if update_location: 51 | r = self.set_location(lat, lng, city, country, name, **kwargs) 52 | if r[0] != 204: 53 | raise Exception("Error updating location: " + str(r)) 54 | 55 | else: 56 | r = self.refresh_all_tokens(**kwargs) 57 | if r[0] != 200: 58 | raise Exception("Error creating new account: " + str(r)) 59 | 60 | def _send_request(self, method, endpoint, params=None, payload=None, **kwargs): 61 | url = self.api_url.format(endpoint) 62 | headers = {'User-Agent': 'Jodel/{} Dalvik/2.1.0 (Linux; U; Android 5.1.1; )'.format(self.version), 63 | 'Accept-Encoding': 'gzip', 64 | 'Content-Type': 'application/json; charset=UTF-8', 65 | 'Authorization': 'Bearer ' + self.access_token if self.access_token else None} 66 | 67 | for _ in range(3): 68 | self._sign_request(method, url, headers, params, payload) 69 | resp = s.request(method=method, url=url, params=params, json=payload, headers=headers, **kwargs) 70 | if resp.status_code != 502: # Retry on error 502 "Bad Gateway" 71 | break 72 | 73 | try: 74 | resp_text = resp.json(encoding="utf-8") 75 | except: 76 | resp_text = resp.text 77 | 78 | return resp.status_code, resp_text 79 | 80 | def _sign_request(self, method, url, headers, params=None, payload=None): 81 | timestamp = datetime.datetime.utcnow().isoformat()[:-7] + "Z" 82 | 83 | req = [method, 84 | urlparse(url).netloc, 85 | "443", 86 | urlparse(url).path, 87 | self.access_token if self.access_token else "", 88 | timestamp, 89 | "%".join(sorted("{}%{}".format(key, value) for key, value in (params if params else {}).items())), 90 | json.dumps(payload) if payload else ""] 91 | 92 | if self.is_legacy: 93 | secret, version = self.secret_legacy, self.version_legacy 94 | else: 95 | secret, version = self.secret, self.version 96 | 97 | signature = hmac.new(secret, "%".join(req).encode("utf-8"), sha1).hexdigest().upper() 98 | 99 | headers['X-Authorization'] = 'HMAC ' + signature 100 | headers['X-Client-Type'] = 'android_{}'.format(version) 101 | headers['X-Timestamp'] = timestamp 102 | headers['X-Api-Version'] = '0.2' 103 | 104 | @staticmethod 105 | def _get_location_dict(lat, lng, city, country=None, name=None): 106 | return {"loc_accuracy": 0.0, 107 | "city": city, 108 | "loc_coordinates": {"lat": lat, "lng": lng}, 109 | "country": country if country else "DE", 110 | "name": name if name else city} 111 | 112 | def get_account_data(self): 113 | return {'expiration_date': self.expiration_date, 'distinct_id': self.distinct_id, 114 | 'refresh_token': self.refresh_token, 'device_uid': self.device_uid, 'access_token': self.access_token, 115 | 'is_legacy': self.is_legacy} 116 | 117 | def refresh_all_tokens(self, **kwargs): 118 | """ Creates a new account with random ID if self.device_uid is not set. Otherwise renews all tokens of the 119 | account with ID = self.device_uid. """ 120 | if not self.device_uid: 121 | print("Creating new account.") 122 | self.is_legacy = False 123 | self.device_uid = ''.join(random.choice('abcdef0123456789') for _ in range(64)) 124 | 125 | payload = {"client_id": self.client_id, 126 | "device_uid": self.device_uid, 127 | "location": self.location_dict} 128 | 129 | resp = self._send_request("POST", "/v2/users", payload=payload, **kwargs) 130 | if resp[0] == 200: 131 | self.access_token = resp[1]['access_token'] 132 | self.expiration_date = resp[1]['expiration_date'] 133 | self.refresh_token = resp[1]['refresh_token'] 134 | self.distinct_id = resp[1]['distinct_id'] 135 | else: 136 | raise Exception(resp) 137 | return resp 138 | 139 | def refresh_access_token(self, **kwargs): 140 | payload = {"client_id": self.client_id, 141 | "distinct_id": self.distinct_id, 142 | "refresh_token": self.refresh_token} 143 | 144 | resp = self._send_request("POST", "/v2/users/refreshToken", payload=payload, **kwargs) 145 | if resp[0] == 200: 146 | self.access_token = resp[1]['access_token'] 147 | self.expiration_date = resp[1]['expiration_date'] 148 | return resp 149 | 150 | def send_push_token(self, push_token, **kwargs): 151 | payload={"client_id": self.client_id, "push_token": push_token} 152 | return self._send_request("PUT", "/v2/users/pushToken", payload=payload, **kwargs) 153 | 154 | def verify_push(self, server_time, verification_code, **kwargs): 155 | payload={"server_time": server_time, "verification_code": verification_code} 156 | return self._send_request("POST", "/v3/user/verification/push", payload=payload, **kwargs) 157 | 158 | def verify(self, android_account=None, **kwargs): 159 | if not android_account: 160 | android_account = gcmhack.AndroidAccount(**kwargs) 161 | time.sleep(5) 162 | 163 | token = android_account.get_push_token(**kwargs) 164 | 165 | for i in range(3): 166 | r = self.send_push_token(token, **kwargs) 167 | if r[0] != 204: 168 | return r 169 | 170 | try: 171 | verification = self._read_verificiation(android_account) 172 | 173 | status, r = self.verify_push(verification['server_time'], verification['verification_code'], **kwargs) 174 | if status == 200 or i == 2: 175 | return status, r 176 | except gcmhack.GcmException: 177 | if i == 2: 178 | raise 179 | 180 | def _read_verificiation(self, android_account): 181 | for j in range(3): 182 | try: 183 | return android_account.receive_verification_from_gcm() 184 | except gcmhack.GcmException: 185 | if j == 2: 186 | raise 187 | 188 | # ################# # 189 | # GET POSTS METHODS # 190 | # ################# # 191 | 192 | def _get_posts(self, post_types="", skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None, pictures=False, **kwargs): 193 | category = "mine" if mine else "hashtag" if hashtag else "channel" if channel else "location" 194 | url_params = {"api_version": "v2" if not (hashtag or channel or pictures) else "v3", 195 | "pictures_posts": "pictures" if pictures else "posts", 196 | "category": category, 197 | "post_types": post_types} 198 | params = {"lat": self.lat, 199 | "lng": self.lng, 200 | "skip": skip, 201 | "limit": limit, 202 | "hashtag": hashtag, 203 | "channel": channel, 204 | "after": after} 205 | 206 | url = "/{api_version}/{pictures_posts}/{category}/{post_types}".format(**url_params) 207 | return self._send_request("GET", url, params=params, **kwargs) 208 | 209 | def get_posts_recent(self, skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None, **kwargs): 210 | return self._get_posts('', skip, limit, after, mine, hashtag, channel, **kwargs) 211 | 212 | def get_posts_popular(self, skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None, **kwargs): 213 | return self._get_posts('popular', skip, limit, after, mine, hashtag, channel, **kwargs) 214 | 215 | def get_posts_discussed(self, skip=0, limit=60, after=None, mine=False, hashtag=None, channel=None, **kwargs): 216 | return self._get_posts('discussed', skip, limit, after, mine, hashtag, channel, **kwargs) 217 | 218 | def get_pictures_recent(self, skip=0, limit=60, after=None, **kwargs): 219 | return self._get_posts('', skip, limit, after, pictures=True, **kwargs) 220 | 221 | def get_pictures_popular(self, skip=0, limit=60, after=None, **kwargs): 222 | return self._get_posts('popular', skip, limit, after, pictures=True, **kwargs) 223 | 224 | def get_pictures_discussed(self, skip=0, limit=60, after=None, **kwargs): 225 | return self._get_posts('discussed', skip, limit, after, pictures=True, **kwargs) 226 | 227 | def get_my_pinned_posts(self, skip=0, limit=60, after=None, **kwargs): 228 | return self._get_posts('pinned', skip, limit, after, True, **kwargs) 229 | 230 | def get_my_replied_posts(self, skip=0, limit=60, after=None, **kwargs): 231 | return self._get_posts('replies', skip, limit, after, True, **kwargs) 232 | 233 | def get_my_voted_posts(self, skip=0, limit=60, after=None, **kwargs): 234 | return self._get_posts('votes', skip, limit, after, True, **kwargs) 235 | 236 | def post_search(self, message, skip=0, limit=60, **kwargs): 237 | params = {"skip": skip, "limit": limit} 238 | payload = {"message": message} 239 | return self._send_request("POST", "/v3/posts/search", params=params, payload=payload, **kwargs) 240 | 241 | # ################### # 242 | # SINGLE POST METHODS # 243 | # ################### # 244 | 245 | def create_post(self, message=None, imgpath=None, b64img=None, color=None, ancestor=None, channel="", **kwargs): 246 | if not imgpath and not message and not b64img: 247 | raise ValueError("One of message or imgpath must not be null.") 248 | 249 | payload = {"color": color if color else random.choice(self.post_colors), 250 | "location": self.location_dict, 251 | "ancestor": ancestor, 252 | "message": message, 253 | "channel": channel} 254 | if imgpath: 255 | with open(imgpath, "rb") as f: 256 | imgdata = base64.b64encode(f.read()).decode("utf-8") 257 | payload["image"] = imgdata 258 | elif b64img: 259 | payload["image"] = b64img 260 | 261 | return self._send_request("POST", '/v3/posts/', payload=payload, **kwargs) 262 | 263 | def get_post_details(self, post_id, **kwargs): 264 | return self._send_request("GET", '/v2/posts/{}/'.format(post_id), **kwargs) 265 | 266 | def get_post_details_v3(self, post_id, skip=0, **kwargs): 267 | return self._send_request("GET", '/v3/posts/{}/details'.format(post_id), 268 | params={'details': 'true', 'reply': skip}, **kwargs) 269 | 270 | def upvote(self, post_id, **kwargs): 271 | return self._send_request("PUT", '/v2/posts/{}/upvote/'.format(post_id), **kwargs) 272 | 273 | def downvote(self, post_id, **kwargs): 274 | return self._send_request("PUT", '/v2/posts/{}/downvote/'.format(post_id), **kwargs) 275 | 276 | def give_thanks(self, post_id, **kwargs): 277 | return self._send_request("POST", '/v3/posts/{}/giveThanks'.format(post_id), **kwargs) 278 | 279 | def get_share_url(self, post_id, **kwargs): 280 | return self._send_request("POST", "/v3/posts/{}/share".format(post_id), **kwargs) 281 | 282 | def pin(self, post_id, **kwargs): 283 | return self._send_request("PUT", "/v2/posts/{}/pin".format(post_id), **kwargs) 284 | 285 | def unpin(self, post_id, **kwargs): 286 | return self._send_request("PUT", "/v2/posts/{}/unpin".format(post_id), **kwargs) 287 | 288 | def enable_notifications(self, post_id, **kwargs): 289 | return self._send_request("PUT", "/v2/posts/{}/notifications/enable".format(post_id), **kwargs) 290 | 291 | def disable_notifications(self, post_id, **kwargs): 292 | return self._send_request("PUT", "/v2/posts/{}/notifications/disable".format(post_id), **kwargs) 293 | 294 | def delete_post(self, post_id, **kwargs): 295 | return self._send_request("DELETE", "/v2/posts/{}".format(post_id), **kwargs) 296 | 297 | # ################### # 298 | # STICKY POST METHODS # 299 | # ################### # 300 | 301 | def upvote_sticky_post(self, post_id, **kwargs): 302 | return self._send_request("PUT", "/v3/stickyposts/{}/up".format(post_id), **kwargs) 303 | 304 | def downvote_sticky_post(self, post_id, **kwargs): 305 | return self._send_request("PUT", "/v3/stickyposts/{}/down".format(post_id), **kwargs) 306 | 307 | def dismiss_sticky_post(self, post_id, **kwargs): 308 | return self._send_request("PUT", "/v3/stickyposts/{}/dismiss".format(post_id), **kwargs) 309 | 310 | # #################### # 311 | # NOTIFICATION METHODS # 312 | # #################### # 313 | 314 | def get_notifications(self, **kwargs): 315 | return self._send_request("PUT", "/v3/user/notifications", **kwargs) 316 | 317 | def get_notifications_new(self, **kwargs): 318 | return self._send_request("GET", "/v3/user/notifications/new", **kwargs) 319 | 320 | def notification_read(self, post_id=None, notification_id=None, **kwargs): 321 | if post_id: 322 | return self._send_request("PUT", "/v3/user/notifications/post/{}/read".format(post_id), **kwargs) 323 | elif notification_id: 324 | return self._send_request("PUT", "/v3/user/notifications/{}/read".format(notification_id), **kwargs) 325 | else: 326 | raise ValueError("One of post_id or notification_id must not be null.") 327 | 328 | # ############### # 329 | # CHANNEL METHODS # 330 | # ############### # 331 | 332 | def get_recommended_channels(self, **kwargs): 333 | return self._send_request("GET", "/v3/user/recommendedChannels", **kwargs) 334 | 335 | def get_channel_meta(self, channel, **kwargs): 336 | return self._send_request("GET", "/v3/user/channelMeta", params={"channel": channel}, **kwargs) 337 | 338 | def follow_channel(self, channel, **kwargs): 339 | return self._send_request("PUT", "/v3/user/followChannel", params={"channel": channel}, **kwargs) 340 | 341 | def unfollow_channel(self, channel, **kwargs): 342 | return self._send_request("PUT", "/v3/user/unfollowChannel", params={"channel": channel}, **kwargs) 343 | 344 | # ############ # 345 | # USER METHODS # 346 | # ############ # 347 | 348 | def set_location(self, lat, lng, city, country=None, name=None, **kwargs): 349 | self.lat, self.lng, self.location_dict = lat, lng, self._get_location_dict(lat, lng, city, country, name) 350 | return self._send_request("PUT", "/v2/users/location", payload={"location": self.location_dict}, **kwargs) 351 | 352 | def set_user_profile(self, user_type=None, gender=None, age=None, **kwargs): 353 | allowed_user_types = ["high_school", "high_school_graduate", "student", "apprentice", "employee", "other", None] 354 | if user_type and user_type not in allowed_user_types: 355 | raise ValueError("user_type must be one of {}.".format(allowed_user_types)) 356 | 357 | if gender not in ["m", "f", None]: 358 | raise ValueError("gender must be either m or f.") 359 | 360 | return self._send_request("PUT", "/v3/user/profile", payload={"user_type": user_type, "gender": gender, "age": age}, **kwargs) 361 | 362 | def get_karma(self, **kwargs): 363 | return self._send_request("GET", "/v2/users/karma", **kwargs) 364 | 365 | def get_user_config(self, **kwargs): 366 | return self._send_request("GET", "/v3/user/config", **kwargs) 367 | 368 | 369 | # helper function to mock input 370 | def obtain_input(text): 371 | return input(text) 372 | -------------------------------------------------------------------------------- /src/jodel_api/protos/checkin_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: checkin.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='checkin.proto', 20 | package='', 21 | serialized_pb=_b('\n\rcheckin.proto\"\x91\x0c\n\x0e\x43heckinRequest\x12\x0c\n\x04imei\x18\x01 \x01(\t\x12\x11\n\tandroidId\x18\x02 \x01(\x03\x12\x0e\n\x06\x64igest\x18\x03 \x01(\t\x12(\n\x07\x63heckin\x18\x04 \x02(\x0b\x32\x17.CheckinRequest.Checkin\x12\x14\n\x0c\x64\x65siredBuild\x18\x05 \x01(\t\x12\x0e\n\x06locale\x18\x06 \x01(\t\x12\x11\n\tloggingId\x18\x07 \x01(\x03\x12\x15\n\rmarketCheckin\x18\x08 \x01(\t\x12\x12\n\nmacAddress\x18\t \x03(\t\x12\x0c\n\x04meid\x18\n \x01(\t\x12\x15\n\raccountCookie\x18\x0b \x03(\t\x12\x10\n\x08timeZone\x18\x0c \x01(\t\x12\x15\n\rsecurityToken\x18\r \x01(\x06\x12\x0f\n\x07version\x18\x0e \x01(\x05\x12\x0f\n\x07otaCert\x18\x0f \x03(\t\x12\x0e\n\x06serial\x18\x10 \x01(\t\x12\x0b\n\x03\x65sn\x18\x11 \x01(\t\x12\x39\n\x13\x64\x65viceConfiguration\x18\x12 \x01(\x0b\x32\x1c.CheckinRequest.DeviceConfig\x12\x16\n\x0emacAddressType\x18\x13 \x03(\t\x12\x10\n\x08\x66ragment\x18\x14 \x02(\x05\x12\x10\n\x08userName\x18\x15 \x01(\t\x12\x18\n\x10userSerialNumber\x18\x16 \x01(\x05\x1a\x8f\x05\n\x07\x43heckin\x12,\n\x05\x62uild\x18\x01 \x02(\x0b\x32\x1d.CheckinRequest.Checkin.Build\x12\x15\n\rlastCheckinMs\x18\x02 \x01(\x03\x12,\n\x05\x65vent\x18\x03 \x03(\x0b\x32\x1d.CheckinRequest.Checkin.Event\x12/\n\x04stat\x18\x04 \x03(\x0b\x32!.CheckinRequest.Checkin.Statistic\x12\x16\n\x0erequestedGroup\x18\x05 \x03(\t\x12\x14\n\x0c\x63\x65llOperator\x18\x06 \x01(\t\x12\x13\n\x0bsimOperator\x18\x07 \x01(\t\x12\x0f\n\x07roaming\x18\x08 \x01(\t\x12\x12\n\nuserNumber\x18\t \x01(\x05\x1a\x8c\x02\n\x05\x42uild\x12\x13\n\x0b\x66ingerprint\x18\x01 \x01(\t\x12\x10\n\x08hardware\x18\x02 \x01(\t\x12\r\n\x05\x62rand\x18\x03 \x01(\t\x12\r\n\x05radio\x18\x04 \x01(\t\x12\x12\n\nbootloader\x18\x05 \x01(\t\x12\x10\n\x08\x63lientId\x18\x06 \x01(\t\x12\x0c\n\x04time\x18\x07 \x01(\x03\x12\x1a\n\x12packageVersionCode\x18\x08 \x01(\x05\x12\x0e\n\x06\x64\x65vice\x18\t \x01(\t\x12\x12\n\nsdkVersion\x18\n \x01(\x05\x12\r\n\x05model\x18\x0b \x01(\t\x12\x14\n\x0cmanufacturer\x18\x0c \x01(\t\x12\x0f\n\x07product\x18\r \x01(\t\x12\x14\n\x0cotaInstalled\x18\x0e \x01(\x08\x1a\x33\n\x05\x45vent\x12\x0b\n\x03tag\x18\x01 \x01(\t\x12\r\n\x05value\x18\x02 \x01(\t\x12\x0e\n\x06timeMs\x18\x03 \x01(\x03\x1a\x34\n\tStatistic\x12\x0b\n\x03tag\x18\x01 \x02(\t\x12\r\n\x05\x63ount\x18\x02 \x01(\x05\x12\x0b\n\x03sum\x18\x03 \x01(\x02\x1a\x8f\x03\n\x0c\x44\x65viceConfig\x12\x13\n\x0btouchScreen\x18\x01 \x01(\x05\x12\x14\n\x0ckeyboardType\x18\x02 \x01(\x05\x12\x12\n\nnavigation\x18\x03 \x01(\x05\x12\x14\n\x0cscreenLayout\x18\x04 \x01(\x05\x12\x17\n\x0fhasHardKeyboard\x18\x05 \x01(\x08\x12\x1c\n\x14hasFiveWayNavigation\x18\x06 \x01(\x08\x12\x12\n\ndensityDpi\x18\x07 \x01(\x05\x12\x13\n\x0bglEsVersion\x18\x08 \x01(\x05\x12\x15\n\rsharedLibrary\x18\t \x03(\t\x12\x18\n\x10\x61vailableFeature\x18\n \x03(\t\x12\x16\n\x0enativePlatform\x18\x0b \x03(\t\x12\x13\n\x0bwidthPixels\x18\x0c \x01(\x05\x12\x14\n\x0cheightPixels\x18\r \x01(\x05\x12\x0e\n\x06locale\x18\x0e \x03(\t\x12\x13\n\x0bglExtension\x18\x0f \x03(\t\x12\x13\n\x0b\x64\x65viceClass\x18\x10 \x01(\x05\x12\x1c\n\x14maxApkDownloadSizeMb\x18\x11 \x01(\x05\"\x92\x04\n\x0f\x43heckinResponse\x12\x0f\n\x07statsOk\x18\x01 \x01(\x08\x12\'\n\x06intent\x18\x02 \x03(\x0b\x32\x17.CheckinResponse.Intent\x12\x0e\n\x06timeMs\x18\x03 \x01(\x03\x12\x0e\n\x06\x64igest\x18\x04 \x01(\t\x12\x32\n\x07setting\x18\x05 \x03(\x0b\x32!.CheckinResponse.GservicesSetting\x12\x10\n\x08marketOk\x18\x06 \x01(\x08\x12\x11\n\tandroidId\x18\x07 \x01(\x06\x12\x15\n\rsecurityToken\x18\x08 \x01(\x06\x12\x14\n\x0csettingsDiff\x18\t \x01(\x08\x12\x15\n\rdeleteSetting\x18\n \x03(\t\x12\x13\n\x0bversionInfo\x18\x0b \x01(\t\x12\x1d\n\x15\x64\x65viceDataVersionInfo\x18\x0c \x01(\t\x1a\xa2\x01\n\x06Intent\x12\x0e\n\x06\x61\x63tion\x18\x01 \x01(\t\x12\x0f\n\x07\x64\x61taUri\x18\x02 \x01(\t\x12\x10\n\x08mimeType\x18\x03 \x01(\t\x12\x11\n\tjavaClass\x18\x04 \x01(\t\x12,\n\x05\x65xtra\x18\x05 \x03(\x0b\x32\x1d.CheckinResponse.Intent.Extra\x1a$\n\x05\x45xtra\x12\x0c\n\x04name\x18\x06 \x01(\t\x12\r\n\x05value\x18\x07 \x01(\t\x1a/\n\x10GservicesSetting\x12\x0c\n\x04name\x18\x01 \x01(\x0c\x12\r\n\x05value\x18\x02 \x01(\x0c\x42&\n\x16org.microg.gms.checkinB\x0c\x43heckinProto') 22 | ) 23 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 24 | 25 | 26 | 27 | 28 | _CHECKINREQUEST_CHECKIN_BUILD = _descriptor.Descriptor( 29 | name='Build', 30 | full_name='CheckinRequest.Checkin.Build', 31 | filename=None, 32 | file=DESCRIPTOR, 33 | containing_type=None, 34 | fields=[ 35 | _descriptor.FieldDescriptor( 36 | name='fingerprint', full_name='CheckinRequest.Checkin.Build.fingerprint', index=0, 37 | number=1, type=9, cpp_type=9, label=1, 38 | has_default_value=False, default_value=_b("").decode('utf-8'), 39 | message_type=None, enum_type=None, containing_type=None, 40 | is_extension=False, extension_scope=None, 41 | options=None), 42 | _descriptor.FieldDescriptor( 43 | name='hardware', full_name='CheckinRequest.Checkin.Build.hardware', index=1, 44 | number=2, type=9, cpp_type=9, label=1, 45 | has_default_value=False, default_value=_b("").decode('utf-8'), 46 | message_type=None, enum_type=None, containing_type=None, 47 | is_extension=False, extension_scope=None, 48 | options=None), 49 | _descriptor.FieldDescriptor( 50 | name='brand', full_name='CheckinRequest.Checkin.Build.brand', index=2, 51 | number=3, type=9, cpp_type=9, label=1, 52 | has_default_value=False, default_value=_b("").decode('utf-8'), 53 | message_type=None, enum_type=None, containing_type=None, 54 | is_extension=False, extension_scope=None, 55 | options=None), 56 | _descriptor.FieldDescriptor( 57 | name='radio', full_name='CheckinRequest.Checkin.Build.radio', index=3, 58 | number=4, type=9, cpp_type=9, label=1, 59 | has_default_value=False, default_value=_b("").decode('utf-8'), 60 | message_type=None, enum_type=None, containing_type=None, 61 | is_extension=False, extension_scope=None, 62 | options=None), 63 | _descriptor.FieldDescriptor( 64 | name='bootloader', full_name='CheckinRequest.Checkin.Build.bootloader', index=4, 65 | number=5, type=9, cpp_type=9, label=1, 66 | has_default_value=False, default_value=_b("").decode('utf-8'), 67 | message_type=None, enum_type=None, containing_type=None, 68 | is_extension=False, extension_scope=None, 69 | options=None), 70 | _descriptor.FieldDescriptor( 71 | name='clientId', full_name='CheckinRequest.Checkin.Build.clientId', index=5, 72 | number=6, type=9, cpp_type=9, label=1, 73 | has_default_value=False, default_value=_b("").decode('utf-8'), 74 | message_type=None, enum_type=None, containing_type=None, 75 | is_extension=False, extension_scope=None, 76 | options=None), 77 | _descriptor.FieldDescriptor( 78 | name='time', full_name='CheckinRequest.Checkin.Build.time', index=6, 79 | number=7, type=3, cpp_type=2, label=1, 80 | has_default_value=False, default_value=0, 81 | message_type=None, enum_type=None, containing_type=None, 82 | is_extension=False, extension_scope=None, 83 | options=None), 84 | _descriptor.FieldDescriptor( 85 | name='packageVersionCode', full_name='CheckinRequest.Checkin.Build.packageVersionCode', index=7, 86 | number=8, type=5, cpp_type=1, label=1, 87 | has_default_value=False, default_value=0, 88 | message_type=None, enum_type=None, containing_type=None, 89 | is_extension=False, extension_scope=None, 90 | options=None), 91 | _descriptor.FieldDescriptor( 92 | name='device', full_name='CheckinRequest.Checkin.Build.device', index=8, 93 | number=9, type=9, cpp_type=9, label=1, 94 | has_default_value=False, default_value=_b("").decode('utf-8'), 95 | message_type=None, enum_type=None, containing_type=None, 96 | is_extension=False, extension_scope=None, 97 | options=None), 98 | _descriptor.FieldDescriptor( 99 | name='sdkVersion', full_name='CheckinRequest.Checkin.Build.sdkVersion', index=9, 100 | number=10, type=5, cpp_type=1, label=1, 101 | has_default_value=False, default_value=0, 102 | message_type=None, enum_type=None, containing_type=None, 103 | is_extension=False, extension_scope=None, 104 | options=None), 105 | _descriptor.FieldDescriptor( 106 | name='model', full_name='CheckinRequest.Checkin.Build.model', index=10, 107 | number=11, type=9, cpp_type=9, label=1, 108 | has_default_value=False, default_value=_b("").decode('utf-8'), 109 | message_type=None, enum_type=None, containing_type=None, 110 | is_extension=False, extension_scope=None, 111 | options=None), 112 | _descriptor.FieldDescriptor( 113 | name='manufacturer', full_name='CheckinRequest.Checkin.Build.manufacturer', index=11, 114 | number=12, type=9, cpp_type=9, label=1, 115 | has_default_value=False, default_value=_b("").decode('utf-8'), 116 | message_type=None, enum_type=None, containing_type=None, 117 | is_extension=False, extension_scope=None, 118 | options=None), 119 | _descriptor.FieldDescriptor( 120 | name='product', full_name='CheckinRequest.Checkin.Build.product', index=12, 121 | number=13, type=9, cpp_type=9, label=1, 122 | has_default_value=False, default_value=_b("").decode('utf-8'), 123 | message_type=None, enum_type=None, containing_type=None, 124 | is_extension=False, extension_scope=None, 125 | options=None), 126 | _descriptor.FieldDescriptor( 127 | name='otaInstalled', full_name='CheckinRequest.Checkin.Build.otaInstalled', index=13, 128 | number=14, type=8, cpp_type=7, label=1, 129 | has_default_value=False, default_value=False, 130 | message_type=None, enum_type=None, containing_type=None, 131 | is_extension=False, extension_scope=None, 132 | options=None), 133 | ], 134 | extensions=[ 135 | ], 136 | nested_types=[], 137 | enum_types=[ 138 | ], 139 | options=None, 140 | is_extendable=False, 141 | extension_ranges=[], 142 | oneofs=[ 143 | ], 144 | serialized_start=794, 145 | serialized_end=1062, 146 | ) 147 | 148 | _CHECKINREQUEST_CHECKIN_EVENT = _descriptor.Descriptor( 149 | name='Event', 150 | full_name='CheckinRequest.Checkin.Event', 151 | filename=None, 152 | file=DESCRIPTOR, 153 | containing_type=None, 154 | fields=[ 155 | _descriptor.FieldDescriptor( 156 | name='tag', full_name='CheckinRequest.Checkin.Event.tag', index=0, 157 | number=1, type=9, cpp_type=9, label=1, 158 | has_default_value=False, default_value=_b("").decode('utf-8'), 159 | message_type=None, enum_type=None, containing_type=None, 160 | is_extension=False, extension_scope=None, 161 | options=None), 162 | _descriptor.FieldDescriptor( 163 | name='value', full_name='CheckinRequest.Checkin.Event.value', index=1, 164 | number=2, type=9, cpp_type=9, label=1, 165 | has_default_value=False, default_value=_b("").decode('utf-8'), 166 | message_type=None, enum_type=None, containing_type=None, 167 | is_extension=False, extension_scope=None, 168 | options=None), 169 | _descriptor.FieldDescriptor( 170 | name='timeMs', full_name='CheckinRequest.Checkin.Event.timeMs', index=2, 171 | number=3, type=3, cpp_type=2, label=1, 172 | has_default_value=False, default_value=0, 173 | message_type=None, enum_type=None, containing_type=None, 174 | is_extension=False, extension_scope=None, 175 | options=None), 176 | ], 177 | extensions=[ 178 | ], 179 | nested_types=[], 180 | enum_types=[ 181 | ], 182 | options=None, 183 | is_extendable=False, 184 | extension_ranges=[], 185 | oneofs=[ 186 | ], 187 | serialized_start=1064, 188 | serialized_end=1115, 189 | ) 190 | 191 | _CHECKINREQUEST_CHECKIN_STATISTIC = _descriptor.Descriptor( 192 | name='Statistic', 193 | full_name='CheckinRequest.Checkin.Statistic', 194 | filename=None, 195 | file=DESCRIPTOR, 196 | containing_type=None, 197 | fields=[ 198 | _descriptor.FieldDescriptor( 199 | name='tag', full_name='CheckinRequest.Checkin.Statistic.tag', index=0, 200 | number=1, type=9, cpp_type=9, label=2, 201 | has_default_value=False, default_value=_b("").decode('utf-8'), 202 | message_type=None, enum_type=None, containing_type=None, 203 | is_extension=False, extension_scope=None, 204 | options=None), 205 | _descriptor.FieldDescriptor( 206 | name='count', full_name='CheckinRequest.Checkin.Statistic.count', index=1, 207 | number=2, type=5, cpp_type=1, label=1, 208 | has_default_value=False, default_value=0, 209 | message_type=None, enum_type=None, containing_type=None, 210 | is_extension=False, extension_scope=None, 211 | options=None), 212 | _descriptor.FieldDescriptor( 213 | name='sum', full_name='CheckinRequest.Checkin.Statistic.sum', index=2, 214 | number=3, type=2, cpp_type=6, label=1, 215 | has_default_value=False, default_value=0, 216 | message_type=None, enum_type=None, containing_type=None, 217 | is_extension=False, extension_scope=None, 218 | options=None), 219 | ], 220 | extensions=[ 221 | ], 222 | nested_types=[], 223 | enum_types=[ 224 | ], 225 | options=None, 226 | is_extendable=False, 227 | extension_ranges=[], 228 | oneofs=[ 229 | ], 230 | serialized_start=1117, 231 | serialized_end=1169, 232 | ) 233 | 234 | _CHECKINREQUEST_CHECKIN = _descriptor.Descriptor( 235 | name='Checkin', 236 | full_name='CheckinRequest.Checkin', 237 | filename=None, 238 | file=DESCRIPTOR, 239 | containing_type=None, 240 | fields=[ 241 | _descriptor.FieldDescriptor( 242 | name='build', full_name='CheckinRequest.Checkin.build', index=0, 243 | number=1, type=11, cpp_type=10, label=2, 244 | has_default_value=False, default_value=None, 245 | message_type=None, enum_type=None, containing_type=None, 246 | is_extension=False, extension_scope=None, 247 | options=None), 248 | _descriptor.FieldDescriptor( 249 | name='lastCheckinMs', full_name='CheckinRequest.Checkin.lastCheckinMs', index=1, 250 | number=2, type=3, cpp_type=2, label=1, 251 | has_default_value=False, default_value=0, 252 | message_type=None, enum_type=None, containing_type=None, 253 | is_extension=False, extension_scope=None, 254 | options=None), 255 | _descriptor.FieldDescriptor( 256 | name='event', full_name='CheckinRequest.Checkin.event', index=2, 257 | number=3, type=11, cpp_type=10, label=3, 258 | has_default_value=False, default_value=[], 259 | message_type=None, enum_type=None, containing_type=None, 260 | is_extension=False, extension_scope=None, 261 | options=None), 262 | _descriptor.FieldDescriptor( 263 | name='stat', full_name='CheckinRequest.Checkin.stat', index=3, 264 | number=4, type=11, cpp_type=10, label=3, 265 | has_default_value=False, default_value=[], 266 | message_type=None, enum_type=None, containing_type=None, 267 | is_extension=False, extension_scope=None, 268 | options=None), 269 | _descriptor.FieldDescriptor( 270 | name='requestedGroup', full_name='CheckinRequest.Checkin.requestedGroup', index=4, 271 | number=5, type=9, cpp_type=9, label=3, 272 | has_default_value=False, default_value=[], 273 | message_type=None, enum_type=None, containing_type=None, 274 | is_extension=False, extension_scope=None, 275 | options=None), 276 | _descriptor.FieldDescriptor( 277 | name='cellOperator', full_name='CheckinRequest.Checkin.cellOperator', index=5, 278 | number=6, type=9, cpp_type=9, label=1, 279 | has_default_value=False, default_value=_b("").decode('utf-8'), 280 | message_type=None, enum_type=None, containing_type=None, 281 | is_extension=False, extension_scope=None, 282 | options=None), 283 | _descriptor.FieldDescriptor( 284 | name='simOperator', full_name='CheckinRequest.Checkin.simOperator', index=6, 285 | number=7, type=9, cpp_type=9, label=1, 286 | has_default_value=False, default_value=_b("").decode('utf-8'), 287 | message_type=None, enum_type=None, containing_type=None, 288 | is_extension=False, extension_scope=None, 289 | options=None), 290 | _descriptor.FieldDescriptor( 291 | name='roaming', full_name='CheckinRequest.Checkin.roaming', index=7, 292 | number=8, type=9, cpp_type=9, label=1, 293 | has_default_value=False, default_value=_b("").decode('utf-8'), 294 | message_type=None, enum_type=None, containing_type=None, 295 | is_extension=False, extension_scope=None, 296 | options=None), 297 | _descriptor.FieldDescriptor( 298 | name='userNumber', full_name='CheckinRequest.Checkin.userNumber', index=8, 299 | number=9, type=5, cpp_type=1, label=1, 300 | has_default_value=False, default_value=0, 301 | message_type=None, enum_type=None, containing_type=None, 302 | is_extension=False, extension_scope=None, 303 | options=None), 304 | ], 305 | extensions=[ 306 | ], 307 | nested_types=[_CHECKINREQUEST_CHECKIN_BUILD, _CHECKINREQUEST_CHECKIN_EVENT, _CHECKINREQUEST_CHECKIN_STATISTIC, ], 308 | enum_types=[ 309 | ], 310 | options=None, 311 | is_extendable=False, 312 | extension_ranges=[], 313 | oneofs=[ 314 | ], 315 | serialized_start=514, 316 | serialized_end=1169, 317 | ) 318 | 319 | _CHECKINREQUEST_DEVICECONFIG = _descriptor.Descriptor( 320 | name='DeviceConfig', 321 | full_name='CheckinRequest.DeviceConfig', 322 | filename=None, 323 | file=DESCRIPTOR, 324 | containing_type=None, 325 | fields=[ 326 | _descriptor.FieldDescriptor( 327 | name='touchScreen', full_name='CheckinRequest.DeviceConfig.touchScreen', index=0, 328 | number=1, type=5, cpp_type=1, label=1, 329 | has_default_value=False, default_value=0, 330 | message_type=None, enum_type=None, containing_type=None, 331 | is_extension=False, extension_scope=None, 332 | options=None), 333 | _descriptor.FieldDescriptor( 334 | name='keyboardType', full_name='CheckinRequest.DeviceConfig.keyboardType', index=1, 335 | number=2, type=5, cpp_type=1, label=1, 336 | has_default_value=False, default_value=0, 337 | message_type=None, enum_type=None, containing_type=None, 338 | is_extension=False, extension_scope=None, 339 | options=None), 340 | _descriptor.FieldDescriptor( 341 | name='navigation', full_name='CheckinRequest.DeviceConfig.navigation', index=2, 342 | number=3, type=5, cpp_type=1, label=1, 343 | has_default_value=False, default_value=0, 344 | message_type=None, enum_type=None, containing_type=None, 345 | is_extension=False, extension_scope=None, 346 | options=None), 347 | _descriptor.FieldDescriptor( 348 | name='screenLayout', full_name='CheckinRequest.DeviceConfig.screenLayout', index=3, 349 | number=4, type=5, cpp_type=1, label=1, 350 | has_default_value=False, default_value=0, 351 | message_type=None, enum_type=None, containing_type=None, 352 | is_extension=False, extension_scope=None, 353 | options=None), 354 | _descriptor.FieldDescriptor( 355 | name='hasHardKeyboard', full_name='CheckinRequest.DeviceConfig.hasHardKeyboard', index=4, 356 | number=5, type=8, cpp_type=7, label=1, 357 | has_default_value=False, default_value=False, 358 | message_type=None, enum_type=None, containing_type=None, 359 | is_extension=False, extension_scope=None, 360 | options=None), 361 | _descriptor.FieldDescriptor( 362 | name='hasFiveWayNavigation', full_name='CheckinRequest.DeviceConfig.hasFiveWayNavigation', index=5, 363 | number=6, type=8, cpp_type=7, label=1, 364 | has_default_value=False, default_value=False, 365 | message_type=None, enum_type=None, containing_type=None, 366 | is_extension=False, extension_scope=None, 367 | options=None), 368 | _descriptor.FieldDescriptor( 369 | name='densityDpi', full_name='CheckinRequest.DeviceConfig.densityDpi', index=6, 370 | number=7, type=5, cpp_type=1, label=1, 371 | has_default_value=False, default_value=0, 372 | message_type=None, enum_type=None, containing_type=None, 373 | is_extension=False, extension_scope=None, 374 | options=None), 375 | _descriptor.FieldDescriptor( 376 | name='glEsVersion', full_name='CheckinRequest.DeviceConfig.glEsVersion', index=7, 377 | number=8, type=5, cpp_type=1, label=1, 378 | has_default_value=False, default_value=0, 379 | message_type=None, enum_type=None, containing_type=None, 380 | is_extension=False, extension_scope=None, 381 | options=None), 382 | _descriptor.FieldDescriptor( 383 | name='sharedLibrary', full_name='CheckinRequest.DeviceConfig.sharedLibrary', index=8, 384 | number=9, type=9, cpp_type=9, label=3, 385 | has_default_value=False, default_value=[], 386 | message_type=None, enum_type=None, containing_type=None, 387 | is_extension=False, extension_scope=None, 388 | options=None), 389 | _descriptor.FieldDescriptor( 390 | name='availableFeature', full_name='CheckinRequest.DeviceConfig.availableFeature', index=9, 391 | number=10, type=9, cpp_type=9, label=3, 392 | has_default_value=False, default_value=[], 393 | message_type=None, enum_type=None, containing_type=None, 394 | is_extension=False, extension_scope=None, 395 | options=None), 396 | _descriptor.FieldDescriptor( 397 | name='nativePlatform', full_name='CheckinRequest.DeviceConfig.nativePlatform', index=10, 398 | number=11, type=9, cpp_type=9, label=3, 399 | has_default_value=False, default_value=[], 400 | message_type=None, enum_type=None, containing_type=None, 401 | is_extension=False, extension_scope=None, 402 | options=None), 403 | _descriptor.FieldDescriptor( 404 | name='widthPixels', full_name='CheckinRequest.DeviceConfig.widthPixels', index=11, 405 | number=12, type=5, cpp_type=1, label=1, 406 | has_default_value=False, default_value=0, 407 | message_type=None, enum_type=None, containing_type=None, 408 | is_extension=False, extension_scope=None, 409 | options=None), 410 | _descriptor.FieldDescriptor( 411 | name='heightPixels', full_name='CheckinRequest.DeviceConfig.heightPixels', index=12, 412 | number=13, type=5, cpp_type=1, label=1, 413 | has_default_value=False, default_value=0, 414 | message_type=None, enum_type=None, containing_type=None, 415 | is_extension=False, extension_scope=None, 416 | options=None), 417 | _descriptor.FieldDescriptor( 418 | name='locale', full_name='CheckinRequest.DeviceConfig.locale', index=13, 419 | number=14, type=9, cpp_type=9, label=3, 420 | has_default_value=False, default_value=[], 421 | message_type=None, enum_type=None, containing_type=None, 422 | is_extension=False, extension_scope=None, 423 | options=None), 424 | _descriptor.FieldDescriptor( 425 | name='glExtension', full_name='CheckinRequest.DeviceConfig.glExtension', index=14, 426 | number=15, type=9, cpp_type=9, label=3, 427 | has_default_value=False, default_value=[], 428 | message_type=None, enum_type=None, containing_type=None, 429 | is_extension=False, extension_scope=None, 430 | options=None), 431 | _descriptor.FieldDescriptor( 432 | name='deviceClass', full_name='CheckinRequest.DeviceConfig.deviceClass', index=15, 433 | number=16, type=5, cpp_type=1, label=1, 434 | has_default_value=False, default_value=0, 435 | message_type=None, enum_type=None, containing_type=None, 436 | is_extension=False, extension_scope=None, 437 | options=None), 438 | _descriptor.FieldDescriptor( 439 | name='maxApkDownloadSizeMb', full_name='CheckinRequest.DeviceConfig.maxApkDownloadSizeMb', index=16, 440 | number=17, type=5, cpp_type=1, label=1, 441 | has_default_value=False, default_value=0, 442 | message_type=None, enum_type=None, containing_type=None, 443 | is_extension=False, extension_scope=None, 444 | options=None), 445 | ], 446 | extensions=[ 447 | ], 448 | nested_types=[], 449 | enum_types=[ 450 | ], 451 | options=None, 452 | is_extendable=False, 453 | extension_ranges=[], 454 | oneofs=[ 455 | ], 456 | serialized_start=1172, 457 | serialized_end=1571, 458 | ) 459 | 460 | _CHECKINREQUEST = _descriptor.Descriptor( 461 | name='CheckinRequest', 462 | full_name='CheckinRequest', 463 | filename=None, 464 | file=DESCRIPTOR, 465 | containing_type=None, 466 | fields=[ 467 | _descriptor.FieldDescriptor( 468 | name='imei', full_name='CheckinRequest.imei', index=0, 469 | number=1, type=9, cpp_type=9, label=1, 470 | has_default_value=False, default_value=_b("").decode('utf-8'), 471 | message_type=None, enum_type=None, containing_type=None, 472 | is_extension=False, extension_scope=None, 473 | options=None), 474 | _descriptor.FieldDescriptor( 475 | name='androidId', full_name='CheckinRequest.androidId', index=1, 476 | number=2, type=3, cpp_type=2, label=1, 477 | has_default_value=False, default_value=0, 478 | message_type=None, enum_type=None, containing_type=None, 479 | is_extension=False, extension_scope=None, 480 | options=None), 481 | _descriptor.FieldDescriptor( 482 | name='digest', full_name='CheckinRequest.digest', index=2, 483 | number=3, type=9, cpp_type=9, label=1, 484 | has_default_value=False, default_value=_b("").decode('utf-8'), 485 | message_type=None, enum_type=None, containing_type=None, 486 | is_extension=False, extension_scope=None, 487 | options=None), 488 | _descriptor.FieldDescriptor( 489 | name='checkin', full_name='CheckinRequest.checkin', index=3, 490 | number=4, type=11, cpp_type=10, label=2, 491 | has_default_value=False, default_value=None, 492 | message_type=None, enum_type=None, containing_type=None, 493 | is_extension=False, extension_scope=None, 494 | options=None), 495 | _descriptor.FieldDescriptor( 496 | name='desiredBuild', full_name='CheckinRequest.desiredBuild', index=4, 497 | number=5, type=9, cpp_type=9, label=1, 498 | has_default_value=False, default_value=_b("").decode('utf-8'), 499 | message_type=None, enum_type=None, containing_type=None, 500 | is_extension=False, extension_scope=None, 501 | options=None), 502 | _descriptor.FieldDescriptor( 503 | name='locale', full_name='CheckinRequest.locale', index=5, 504 | number=6, type=9, cpp_type=9, label=1, 505 | has_default_value=False, default_value=_b("").decode('utf-8'), 506 | message_type=None, enum_type=None, containing_type=None, 507 | is_extension=False, extension_scope=None, 508 | options=None), 509 | _descriptor.FieldDescriptor( 510 | name='loggingId', full_name='CheckinRequest.loggingId', index=6, 511 | number=7, type=3, cpp_type=2, label=1, 512 | has_default_value=False, default_value=0, 513 | message_type=None, enum_type=None, containing_type=None, 514 | is_extension=False, extension_scope=None, 515 | options=None), 516 | _descriptor.FieldDescriptor( 517 | name='marketCheckin', full_name='CheckinRequest.marketCheckin', index=7, 518 | number=8, type=9, cpp_type=9, label=1, 519 | has_default_value=False, default_value=_b("").decode('utf-8'), 520 | message_type=None, enum_type=None, containing_type=None, 521 | is_extension=False, extension_scope=None, 522 | options=None), 523 | _descriptor.FieldDescriptor( 524 | name='macAddress', full_name='CheckinRequest.macAddress', index=8, 525 | number=9, type=9, cpp_type=9, label=3, 526 | has_default_value=False, default_value=[], 527 | message_type=None, enum_type=None, containing_type=None, 528 | is_extension=False, extension_scope=None, 529 | options=None), 530 | _descriptor.FieldDescriptor( 531 | name='meid', full_name='CheckinRequest.meid', index=9, 532 | number=10, type=9, cpp_type=9, label=1, 533 | has_default_value=False, default_value=_b("").decode('utf-8'), 534 | message_type=None, enum_type=None, containing_type=None, 535 | is_extension=False, extension_scope=None, 536 | options=None), 537 | _descriptor.FieldDescriptor( 538 | name='accountCookie', full_name='CheckinRequest.accountCookie', index=10, 539 | number=11, type=9, cpp_type=9, label=3, 540 | has_default_value=False, default_value=[], 541 | message_type=None, enum_type=None, containing_type=None, 542 | is_extension=False, extension_scope=None, 543 | options=None), 544 | _descriptor.FieldDescriptor( 545 | name='timeZone', full_name='CheckinRequest.timeZone', index=11, 546 | number=12, type=9, cpp_type=9, label=1, 547 | has_default_value=False, default_value=_b("").decode('utf-8'), 548 | message_type=None, enum_type=None, containing_type=None, 549 | is_extension=False, extension_scope=None, 550 | options=None), 551 | _descriptor.FieldDescriptor( 552 | name='securityToken', full_name='CheckinRequest.securityToken', index=12, 553 | number=13, type=6, cpp_type=4, label=1, 554 | has_default_value=False, default_value=0, 555 | message_type=None, enum_type=None, containing_type=None, 556 | is_extension=False, extension_scope=None, 557 | options=None), 558 | _descriptor.FieldDescriptor( 559 | name='version', full_name='CheckinRequest.version', index=13, 560 | number=14, type=5, cpp_type=1, label=1, 561 | has_default_value=False, default_value=0, 562 | message_type=None, enum_type=None, containing_type=None, 563 | is_extension=False, extension_scope=None, 564 | options=None), 565 | _descriptor.FieldDescriptor( 566 | name='otaCert', full_name='CheckinRequest.otaCert', index=14, 567 | number=15, type=9, cpp_type=9, label=3, 568 | has_default_value=False, default_value=[], 569 | message_type=None, enum_type=None, containing_type=None, 570 | is_extension=False, extension_scope=None, 571 | options=None), 572 | _descriptor.FieldDescriptor( 573 | name='serial', full_name='CheckinRequest.serial', index=15, 574 | number=16, type=9, cpp_type=9, label=1, 575 | has_default_value=False, default_value=_b("").decode('utf-8'), 576 | message_type=None, enum_type=None, containing_type=None, 577 | is_extension=False, extension_scope=None, 578 | options=None), 579 | _descriptor.FieldDescriptor( 580 | name='esn', full_name='CheckinRequest.esn', index=16, 581 | number=17, type=9, cpp_type=9, label=1, 582 | has_default_value=False, default_value=_b("").decode('utf-8'), 583 | message_type=None, enum_type=None, containing_type=None, 584 | is_extension=False, extension_scope=None, 585 | options=None), 586 | _descriptor.FieldDescriptor( 587 | name='deviceConfiguration', full_name='CheckinRequest.deviceConfiguration', index=17, 588 | number=18, type=11, cpp_type=10, label=1, 589 | has_default_value=False, default_value=None, 590 | message_type=None, enum_type=None, containing_type=None, 591 | is_extension=False, extension_scope=None, 592 | options=None), 593 | _descriptor.FieldDescriptor( 594 | name='macAddressType', full_name='CheckinRequest.macAddressType', index=18, 595 | number=19, type=9, cpp_type=9, label=3, 596 | has_default_value=False, default_value=[], 597 | message_type=None, enum_type=None, containing_type=None, 598 | is_extension=False, extension_scope=None, 599 | options=None), 600 | _descriptor.FieldDescriptor( 601 | name='fragment', full_name='CheckinRequest.fragment', index=19, 602 | number=20, type=5, cpp_type=1, label=2, 603 | has_default_value=False, default_value=0, 604 | message_type=None, enum_type=None, containing_type=None, 605 | is_extension=False, extension_scope=None, 606 | options=None), 607 | _descriptor.FieldDescriptor( 608 | name='userName', full_name='CheckinRequest.userName', index=20, 609 | number=21, type=9, cpp_type=9, label=1, 610 | has_default_value=False, default_value=_b("").decode('utf-8'), 611 | message_type=None, enum_type=None, containing_type=None, 612 | is_extension=False, extension_scope=None, 613 | options=None), 614 | _descriptor.FieldDescriptor( 615 | name='userSerialNumber', full_name='CheckinRequest.userSerialNumber', index=21, 616 | number=22, type=5, cpp_type=1, label=1, 617 | has_default_value=False, default_value=0, 618 | message_type=None, enum_type=None, containing_type=None, 619 | is_extension=False, extension_scope=None, 620 | options=None), 621 | ], 622 | extensions=[ 623 | ], 624 | nested_types=[_CHECKINREQUEST_CHECKIN, _CHECKINREQUEST_DEVICECONFIG, ], 625 | enum_types=[ 626 | ], 627 | options=None, 628 | is_extendable=False, 629 | extension_ranges=[], 630 | oneofs=[ 631 | ], 632 | serialized_start=18, 633 | serialized_end=1571, 634 | ) 635 | 636 | 637 | _CHECKINRESPONSE_INTENT_EXTRA = _descriptor.Descriptor( 638 | name='Extra', 639 | full_name='CheckinResponse.Intent.Extra', 640 | filename=None, 641 | file=DESCRIPTOR, 642 | containing_type=None, 643 | fields=[ 644 | _descriptor.FieldDescriptor( 645 | name='name', full_name='CheckinResponse.Intent.Extra.name', index=0, 646 | number=6, type=9, cpp_type=9, label=1, 647 | has_default_value=False, default_value=_b("").decode('utf-8'), 648 | message_type=None, enum_type=None, containing_type=None, 649 | is_extension=False, extension_scope=None, 650 | options=None), 651 | _descriptor.FieldDescriptor( 652 | name='value', full_name='CheckinResponse.Intent.Extra.value', index=1, 653 | number=7, type=9, cpp_type=9, label=1, 654 | has_default_value=False, default_value=_b("").decode('utf-8'), 655 | message_type=None, enum_type=None, containing_type=None, 656 | is_extension=False, extension_scope=None, 657 | options=None), 658 | ], 659 | extensions=[ 660 | ], 661 | nested_types=[], 662 | enum_types=[ 663 | ], 664 | options=None, 665 | is_extendable=False, 666 | extension_ranges=[], 667 | oneofs=[ 668 | ], 669 | serialized_start=2019, 670 | serialized_end=2055, 671 | ) 672 | 673 | _CHECKINRESPONSE_INTENT = _descriptor.Descriptor( 674 | name='Intent', 675 | full_name='CheckinResponse.Intent', 676 | filename=None, 677 | file=DESCRIPTOR, 678 | containing_type=None, 679 | fields=[ 680 | _descriptor.FieldDescriptor( 681 | name='action', full_name='CheckinResponse.Intent.action', index=0, 682 | number=1, type=9, cpp_type=9, label=1, 683 | has_default_value=False, default_value=_b("").decode('utf-8'), 684 | message_type=None, enum_type=None, containing_type=None, 685 | is_extension=False, extension_scope=None, 686 | options=None), 687 | _descriptor.FieldDescriptor( 688 | name='dataUri', full_name='CheckinResponse.Intent.dataUri', index=1, 689 | number=2, type=9, cpp_type=9, label=1, 690 | has_default_value=False, default_value=_b("").decode('utf-8'), 691 | message_type=None, enum_type=None, containing_type=None, 692 | is_extension=False, extension_scope=None, 693 | options=None), 694 | _descriptor.FieldDescriptor( 695 | name='mimeType', full_name='CheckinResponse.Intent.mimeType', index=2, 696 | number=3, type=9, cpp_type=9, label=1, 697 | has_default_value=False, default_value=_b("").decode('utf-8'), 698 | message_type=None, enum_type=None, containing_type=None, 699 | is_extension=False, extension_scope=None, 700 | options=None), 701 | _descriptor.FieldDescriptor( 702 | name='javaClass', full_name='CheckinResponse.Intent.javaClass', index=3, 703 | number=4, type=9, cpp_type=9, label=1, 704 | has_default_value=False, default_value=_b("").decode('utf-8'), 705 | message_type=None, enum_type=None, containing_type=None, 706 | is_extension=False, extension_scope=None, 707 | options=None), 708 | _descriptor.FieldDescriptor( 709 | name='extra', full_name='CheckinResponse.Intent.extra', index=4, 710 | number=5, type=11, cpp_type=10, label=3, 711 | has_default_value=False, default_value=[], 712 | message_type=None, enum_type=None, containing_type=None, 713 | is_extension=False, extension_scope=None, 714 | options=None), 715 | ], 716 | extensions=[ 717 | ], 718 | nested_types=[_CHECKINRESPONSE_INTENT_EXTRA, ], 719 | enum_types=[ 720 | ], 721 | options=None, 722 | is_extendable=False, 723 | extension_ranges=[], 724 | oneofs=[ 725 | ], 726 | serialized_start=1893, 727 | serialized_end=2055, 728 | ) 729 | 730 | _CHECKINRESPONSE_GSERVICESSETTING = _descriptor.Descriptor( 731 | name='GservicesSetting', 732 | full_name='CheckinResponse.GservicesSetting', 733 | filename=None, 734 | file=DESCRIPTOR, 735 | containing_type=None, 736 | fields=[ 737 | _descriptor.FieldDescriptor( 738 | name='name', full_name='CheckinResponse.GservicesSetting.name', index=0, 739 | number=1, type=12, cpp_type=9, label=1, 740 | has_default_value=False, default_value=_b(""), 741 | message_type=None, enum_type=None, containing_type=None, 742 | is_extension=False, extension_scope=None, 743 | options=None), 744 | _descriptor.FieldDescriptor( 745 | name='value', full_name='CheckinResponse.GservicesSetting.value', index=1, 746 | number=2, type=12, cpp_type=9, label=1, 747 | has_default_value=False, default_value=_b(""), 748 | message_type=None, enum_type=None, containing_type=None, 749 | is_extension=False, extension_scope=None, 750 | options=None), 751 | ], 752 | extensions=[ 753 | ], 754 | nested_types=[], 755 | enum_types=[ 756 | ], 757 | options=None, 758 | is_extendable=False, 759 | extension_ranges=[], 760 | oneofs=[ 761 | ], 762 | serialized_start=2057, 763 | serialized_end=2104, 764 | ) 765 | 766 | _CHECKINRESPONSE = _descriptor.Descriptor( 767 | name='CheckinResponse', 768 | full_name='CheckinResponse', 769 | filename=None, 770 | file=DESCRIPTOR, 771 | containing_type=None, 772 | fields=[ 773 | _descriptor.FieldDescriptor( 774 | name='statsOk', full_name='CheckinResponse.statsOk', index=0, 775 | number=1, type=8, cpp_type=7, label=1, 776 | has_default_value=False, default_value=False, 777 | message_type=None, enum_type=None, containing_type=None, 778 | is_extension=False, extension_scope=None, 779 | options=None), 780 | _descriptor.FieldDescriptor( 781 | name='intent', full_name='CheckinResponse.intent', index=1, 782 | number=2, type=11, cpp_type=10, label=3, 783 | has_default_value=False, default_value=[], 784 | message_type=None, enum_type=None, containing_type=None, 785 | is_extension=False, extension_scope=None, 786 | options=None), 787 | _descriptor.FieldDescriptor( 788 | name='timeMs', full_name='CheckinResponse.timeMs', index=2, 789 | number=3, type=3, cpp_type=2, label=1, 790 | has_default_value=False, default_value=0, 791 | message_type=None, enum_type=None, containing_type=None, 792 | is_extension=False, extension_scope=None, 793 | options=None), 794 | _descriptor.FieldDescriptor( 795 | name='digest', full_name='CheckinResponse.digest', index=3, 796 | number=4, type=9, cpp_type=9, label=1, 797 | has_default_value=False, default_value=_b("").decode('utf-8'), 798 | message_type=None, enum_type=None, containing_type=None, 799 | is_extension=False, extension_scope=None, 800 | options=None), 801 | _descriptor.FieldDescriptor( 802 | name='setting', full_name='CheckinResponse.setting', index=4, 803 | number=5, type=11, cpp_type=10, label=3, 804 | has_default_value=False, default_value=[], 805 | message_type=None, enum_type=None, containing_type=None, 806 | is_extension=False, extension_scope=None, 807 | options=None), 808 | _descriptor.FieldDescriptor( 809 | name='marketOk', full_name='CheckinResponse.marketOk', index=5, 810 | number=6, type=8, cpp_type=7, label=1, 811 | has_default_value=False, default_value=False, 812 | message_type=None, enum_type=None, containing_type=None, 813 | is_extension=False, extension_scope=None, 814 | options=None), 815 | _descriptor.FieldDescriptor( 816 | name='androidId', full_name='CheckinResponse.androidId', index=6, 817 | number=7, type=6, cpp_type=4, label=1, 818 | has_default_value=False, default_value=0, 819 | message_type=None, enum_type=None, containing_type=None, 820 | is_extension=False, extension_scope=None, 821 | options=None), 822 | _descriptor.FieldDescriptor( 823 | name='securityToken', full_name='CheckinResponse.securityToken', index=7, 824 | number=8, type=6, cpp_type=4, label=1, 825 | has_default_value=False, default_value=0, 826 | message_type=None, enum_type=None, containing_type=None, 827 | is_extension=False, extension_scope=None, 828 | options=None), 829 | _descriptor.FieldDescriptor( 830 | name='settingsDiff', full_name='CheckinResponse.settingsDiff', index=8, 831 | number=9, type=8, cpp_type=7, label=1, 832 | has_default_value=False, default_value=False, 833 | message_type=None, enum_type=None, containing_type=None, 834 | is_extension=False, extension_scope=None, 835 | options=None), 836 | _descriptor.FieldDescriptor( 837 | name='deleteSetting', full_name='CheckinResponse.deleteSetting', index=9, 838 | number=10, type=9, cpp_type=9, label=3, 839 | has_default_value=False, default_value=[], 840 | message_type=None, enum_type=None, containing_type=None, 841 | is_extension=False, extension_scope=None, 842 | options=None), 843 | _descriptor.FieldDescriptor( 844 | name='versionInfo', full_name='CheckinResponse.versionInfo', index=10, 845 | number=11, type=9, cpp_type=9, label=1, 846 | has_default_value=False, default_value=_b("").decode('utf-8'), 847 | message_type=None, enum_type=None, containing_type=None, 848 | is_extension=False, extension_scope=None, 849 | options=None), 850 | _descriptor.FieldDescriptor( 851 | name='deviceDataVersionInfo', full_name='CheckinResponse.deviceDataVersionInfo', index=11, 852 | number=12, type=9, cpp_type=9, label=1, 853 | has_default_value=False, default_value=_b("").decode('utf-8'), 854 | message_type=None, enum_type=None, containing_type=None, 855 | is_extension=False, extension_scope=None, 856 | options=None), 857 | ], 858 | extensions=[ 859 | ], 860 | nested_types=[_CHECKINRESPONSE_INTENT, _CHECKINRESPONSE_GSERVICESSETTING, ], 861 | enum_types=[ 862 | ], 863 | options=None, 864 | is_extendable=False, 865 | extension_ranges=[], 866 | oneofs=[ 867 | ], 868 | serialized_start=1574, 869 | serialized_end=2104, 870 | ) 871 | 872 | _CHECKINREQUEST_CHECKIN_BUILD.containing_type = _CHECKINREQUEST_CHECKIN 873 | _CHECKINREQUEST_CHECKIN_EVENT.containing_type = _CHECKINREQUEST_CHECKIN 874 | _CHECKINREQUEST_CHECKIN_STATISTIC.containing_type = _CHECKINREQUEST_CHECKIN 875 | _CHECKINREQUEST_CHECKIN.fields_by_name['build'].message_type = _CHECKINREQUEST_CHECKIN_BUILD 876 | _CHECKINREQUEST_CHECKIN.fields_by_name['event'].message_type = _CHECKINREQUEST_CHECKIN_EVENT 877 | _CHECKINREQUEST_CHECKIN.fields_by_name['stat'].message_type = _CHECKINREQUEST_CHECKIN_STATISTIC 878 | _CHECKINREQUEST_CHECKIN.containing_type = _CHECKINREQUEST 879 | _CHECKINREQUEST_DEVICECONFIG.containing_type = _CHECKINREQUEST 880 | _CHECKINREQUEST.fields_by_name['checkin'].message_type = _CHECKINREQUEST_CHECKIN 881 | _CHECKINREQUEST.fields_by_name['deviceConfiguration'].message_type = _CHECKINREQUEST_DEVICECONFIG 882 | _CHECKINRESPONSE_INTENT_EXTRA.containing_type = _CHECKINRESPONSE_INTENT 883 | _CHECKINRESPONSE_INTENT.fields_by_name['extra'].message_type = _CHECKINRESPONSE_INTENT_EXTRA 884 | _CHECKINRESPONSE_INTENT.containing_type = _CHECKINRESPONSE 885 | _CHECKINRESPONSE_GSERVICESSETTING.containing_type = _CHECKINRESPONSE 886 | _CHECKINRESPONSE.fields_by_name['intent'].message_type = _CHECKINRESPONSE_INTENT 887 | _CHECKINRESPONSE.fields_by_name['setting'].message_type = _CHECKINRESPONSE_GSERVICESSETTING 888 | DESCRIPTOR.message_types_by_name['CheckinRequest'] = _CHECKINREQUEST 889 | DESCRIPTOR.message_types_by_name['CheckinResponse'] = _CHECKINRESPONSE 890 | 891 | CheckinRequest = _reflection.GeneratedProtocolMessageType('CheckinRequest', (_message.Message,), dict( 892 | 893 | Checkin = _reflection.GeneratedProtocolMessageType('Checkin', (_message.Message,), dict( 894 | 895 | Build = _reflection.GeneratedProtocolMessageType('Build', (_message.Message,), dict( 896 | DESCRIPTOR = _CHECKINREQUEST_CHECKIN_BUILD, 897 | __module__ = 'checkin_pb2' 898 | # @@protoc_insertion_point(class_scope:CheckinRequest.Checkin.Build) 899 | )) 900 | , 901 | 902 | Event = _reflection.GeneratedProtocolMessageType('Event', (_message.Message,), dict( 903 | DESCRIPTOR = _CHECKINREQUEST_CHECKIN_EVENT, 904 | __module__ = 'checkin_pb2' 905 | # @@protoc_insertion_point(class_scope:CheckinRequest.Checkin.Event) 906 | )) 907 | , 908 | 909 | Statistic = _reflection.GeneratedProtocolMessageType('Statistic', (_message.Message,), dict( 910 | DESCRIPTOR = _CHECKINREQUEST_CHECKIN_STATISTIC, 911 | __module__ = 'checkin_pb2' 912 | # @@protoc_insertion_point(class_scope:CheckinRequest.Checkin.Statistic) 913 | )) 914 | , 915 | DESCRIPTOR = _CHECKINREQUEST_CHECKIN, 916 | __module__ = 'checkin_pb2' 917 | # @@protoc_insertion_point(class_scope:CheckinRequest.Checkin) 918 | )) 919 | , 920 | 921 | DeviceConfig = _reflection.GeneratedProtocolMessageType('DeviceConfig', (_message.Message,), dict( 922 | DESCRIPTOR = _CHECKINREQUEST_DEVICECONFIG, 923 | __module__ = 'checkin_pb2' 924 | # @@protoc_insertion_point(class_scope:CheckinRequest.DeviceConfig) 925 | )) 926 | , 927 | DESCRIPTOR = _CHECKINREQUEST, 928 | __module__ = 'checkin_pb2' 929 | # @@protoc_insertion_point(class_scope:CheckinRequest) 930 | )) 931 | _sym_db.RegisterMessage(CheckinRequest) 932 | _sym_db.RegisterMessage(CheckinRequest.Checkin) 933 | _sym_db.RegisterMessage(CheckinRequest.Checkin.Build) 934 | _sym_db.RegisterMessage(CheckinRequest.Checkin.Event) 935 | _sym_db.RegisterMessage(CheckinRequest.Checkin.Statistic) 936 | _sym_db.RegisterMessage(CheckinRequest.DeviceConfig) 937 | 938 | CheckinResponse = _reflection.GeneratedProtocolMessageType('CheckinResponse', (_message.Message,), dict( 939 | 940 | Intent = _reflection.GeneratedProtocolMessageType('Intent', (_message.Message,), dict( 941 | 942 | Extra = _reflection.GeneratedProtocolMessageType('Extra', (_message.Message,), dict( 943 | DESCRIPTOR = _CHECKINRESPONSE_INTENT_EXTRA, 944 | __module__ = 'checkin_pb2' 945 | # @@protoc_insertion_point(class_scope:CheckinResponse.Intent.Extra) 946 | )) 947 | , 948 | DESCRIPTOR = _CHECKINRESPONSE_INTENT, 949 | __module__ = 'checkin_pb2' 950 | # @@protoc_insertion_point(class_scope:CheckinResponse.Intent) 951 | )) 952 | , 953 | 954 | GservicesSetting = _reflection.GeneratedProtocolMessageType('GservicesSetting', (_message.Message,), dict( 955 | DESCRIPTOR = _CHECKINRESPONSE_GSERVICESSETTING, 956 | __module__ = 'checkin_pb2' 957 | # @@protoc_insertion_point(class_scope:CheckinResponse.GservicesSetting) 958 | )) 959 | , 960 | DESCRIPTOR = _CHECKINRESPONSE, 961 | __module__ = 'checkin_pb2' 962 | # @@protoc_insertion_point(class_scope:CheckinResponse) 963 | )) 964 | _sym_db.RegisterMessage(CheckinResponse) 965 | _sym_db.RegisterMessage(CheckinResponse.Intent) 966 | _sym_db.RegisterMessage(CheckinResponse.Intent.Extra) 967 | _sym_db.RegisterMessage(CheckinResponse.GservicesSetting) 968 | 969 | 970 | DESCRIPTOR.has_options = True 971 | DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\026org.microg.gms.checkinB\014CheckinProto')) 972 | # @@protoc_insertion_point(module_scope) 973 | -------------------------------------------------------------------------------- /src/jodel_api/protos/mcs_pb2.py: -------------------------------------------------------------------------------- 1 | # Generated by the protocol buffer compiler. DO NOT EDIT! 2 | # source: mcs.proto 3 | 4 | import sys 5 | _b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1')) 6 | from google.protobuf import descriptor as _descriptor 7 | from google.protobuf import message as _message 8 | from google.protobuf import reflection as _reflection 9 | from google.protobuf import symbol_database as _symbol_database 10 | from google.protobuf import descriptor_pb2 11 | # @@protoc_insertion_point(imports) 12 | 13 | _sym_db = _symbol_database.Default() 14 | 15 | 16 | 17 | 18 | DESCRIPTOR = _descriptor.FileDescriptor( 19 | name='mcs.proto', 20 | package='', 21 | serialized_pb=_b('\n\tmcs.proto\"S\n\rHeartbeatPing\x12\x11\n\tstream_id\x18\x01 \x01(\x05\x12\x1f\n\x17last_stream_id_received\x18\x02 \x01(\x05\x12\x0e\n\x06status\x18\x03 \x01(\x03\"R\n\x0cHeartbeatAck\x12\x11\n\tstream_id\x18\x01 \x01(\x05\x12\x1f\n\x17last_stream_id_received\x18\x02 \x01(\x05\x12\x0e\n\x06status\x18\x03 \x01(\x03\"W\n\tErrorInfo\x12\x0c\n\x04\x63ode\x18\x01 \x02(\x05\x12\x0f\n\x07message\x18\x02 \x01(\t\x12\x0c\n\x04type\x18\x03 \x01(\t\x12\x1d\n\textension\x18\x04 \x01(\x0b\x32\n.Extension\"&\n\x07Setting\x12\x0c\n\x04name\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x02(\t\"A\n\rHeartbeatStat\x12\n\n\x02ip\x18\x01 \x02(\t\x12\x0f\n\x07timeout\x18\x02 \x02(\x08\x12\x13\n\x0binterval_ms\x18\x03 \x02(\x05\"G\n\x0fHeartbeatConfig\x12\x13\n\x0bupload_stat\x18\x01 \x01(\x08\x12\n\n\x02ip\x18\x02 \x01(\t\x12\x13\n\x0binterval_ms\x18\x03 \x01(\x05\"\xcf\x03\n\x0cLoginRequest\x12\n\n\x02id\x18\x01 \x02(\t\x12\x0e\n\x06\x64omain\x18\x02 \x02(\t\x12\x0c\n\x04user\x18\x03 \x02(\t\x12\x10\n\x08resource\x18\x04 \x02(\t\x12\x12\n\nauth_token\x18\x05 \x02(\t\x12\x11\n\tdevice_id\x18\x06 \x01(\t\x12\x13\n\x0blast_rmq_id\x18\x07 \x01(\x03\x12\x19\n\x07setting\x18\x08 \x03(\x0b\x32\x08.Setting\x12\x10\n\x08\x63ompress\x18\t \x01(\x05\x12\x1e\n\x16received_persistent_id\x18\n \x03(\t\x12\x1a\n\x12include_stream_ids\x18\x0b \x01(\x08\x12\x1a\n\x12\x61\x64\x61ptive_heartbeat\x18\x0c \x01(\x08\x12&\n\x0eheartbeat_stat\x18\r \x01(\x0b\x32\x0e.HeartbeatStat\x12\x10\n\x08use_rmq2\x18\x0e \x01(\x08\x12\x12\n\naccount_id\x18\x0f \x01(\x03\x12/\n\x0c\x61uth_service\x18\x10 \x01(\x0e\x32\x19.LoginRequest.AuthService\x12\x14\n\x0cnetwork_type\x18\x11 \x01(\x05\x12\x0e\n\x06status\x18\x12 \x01(\x03\"\x1d\n\x0b\x41uthService\x12\x0e\n\nANDROID_ID\x10\x02\"\xd8\x01\n\rLoginResponse\x12\n\n\x02id\x18\x01 \x02(\t\x12\x0b\n\x03jid\x18\x02 \x01(\t\x12\x19\n\x05\x65rror\x18\x03 \x01(\x0b\x32\n.ErrorInfo\x12\x19\n\x07setting\x18\x04 \x03(\x0b\x32\x08.Setting\x12\x11\n\tstream_id\x18\x05 \x01(\x05\x12\x1f\n\x17last_stream_id_received\x18\x06 \x01(\x05\x12*\n\x10heartbeat_config\x18\x07 \x01(\x0b\x32\x10.HeartbeatConfig\x12\x18\n\x10server_timestamp\x18\x08 \x01(\x03\"/\n\x11StreamErrorStanza\x12\x0c\n\x04type\x18\x01 \x02(\t\x12\x0c\n\x04text\x18\x02 \x01(\t\"\x07\n\x05\x43lose\"%\n\tExtension\x12\n\n\x02id\x18\x01 \x02(\x05\x12\x0c\n\x04\x64\x61ta\x18\x02 \x02(\x0c\"\xbf\x02\n\x08IqStanza\x12\x0e\n\x06rmq_id\x18\x01 \x01(\x03\x12\x1e\n\x04type\x18\x02 \x02(\x0e\x32\x10.IqStanza.IqType\x12\n\n\x02id\x18\x03 \x02(\t\x12\x0c\n\x04\x66rom\x18\x04 \x01(\t\x12\n\n\x02to\x18\x05 \x01(\t\x12\x19\n\x05\x65rror\x18\x06 \x01(\x0b\x32\n.ErrorInfo\x12\x1d\n\textension\x18\x07 \x01(\x0b\x32\n.Extension\x12\x15\n\rpersistent_id\x18\x08 \x01(\t\x12\x11\n\tstream_id\x18\t \x01(\x05\x12\x1f\n\x17last_stream_id_received\x18\n \x01(\x05\x12\x12\n\naccount_id\x18\x0b \x01(\x03\x12\x0e\n\x06status\x18\x0c \x01(\x03\"4\n\x06IqType\x12\x07\n\x03GET\x10\x00\x12\x07\n\x03SET\x10\x01\x12\n\n\x06RESULT\x10\x02\x12\x0c\n\x08IQ_ERROR\x10\x03\"%\n\x07\x41ppData\x12\x0b\n\x03key\x18\x01 \x02(\t\x12\r\n\x05value\x18\x02 \x02(\t\"\xb0\x03\n\x11\x44\x61taMessageStanza\x12\x0e\n\x06rmq_id\x18\x01 \x01(\x03\x12\n\n\x02id\x18\x02 \x01(\t\x12\x0c\n\x04\x66rom\x18\x03 \x02(\t\x12\n\n\x02to\x18\x04 \x01(\t\x12\x10\n\x08\x63\x61tegory\x18\x05 \x02(\t\x12\r\n\x05token\x18\x06 \x01(\t\x12\x1a\n\x08\x61pp_data\x18\x07 \x03(\x0b\x32\x08.AppData\x12\x1b\n\x13\x66rom_trusted_server\x18\x08 \x01(\x08\x12\x15\n\rpersistent_id\x18\t \x01(\t\x12\x11\n\tstream_id\x18\n \x01(\x05\x12\x1f\n\x17last_stream_id_received\x18\x0b \x01(\x05\x12\x12\n\npermission\x18\x0c \x01(\t\x12\x0e\n\x06reg_id\x18\r \x01(\t\x12\x15\n\rpkg_signature\x18\x0e \x01(\t\x12\x11\n\tclient_id\x18\x0f \x01(\t\x12\x16\n\x0e\x64\x65vice_user_id\x18\x10 \x01(\x03\x12\x0b\n\x03ttl\x18\x11 \x01(\x05\x12\x0c\n\x04sent\x18\x12 \x01(\x03\x12\x0e\n\x06queued\x18\x13 \x01(\x05\x12\x0e\n\x06status\x18\x14 \x01(\x03\x12\x10\n\x08raw_data\x18\x15 \x01(\x0c\x12\r\n\x05\x64\x65lay\x18\x16 \x01(\x05\"\x0b\n\tStreamAck\"\x1a\n\x0cSelectiveAck\x12\n\n\x02id\x18\x01 \x03(\t\"x\n\x12\x42indAccountRequest\x12\x10\n\x08packetid\x18\x01 \x01(\t\x12\x0e\n\x06\x64omain\x18\x02 \x01(\t\x12\x0c\n\x04user\x18\x03 \x01(\t\x12\x10\n\x08resource\x18\x04 \x01(\t\x12\x11\n\taccountid\x18\t \x01(\x03\x12\r\n\x05token\x18\x05 \x01(\t\"w\n\x13\x42indAccountResponse\x12\x10\n\x08packetid\x18\x01 \x01(\t\x12\x0b\n\x03jid\x18\x02 \x01(\t\x12\x14\n\x0claststreamid\x18\x05 \x01(\x05\x12\x10\n\x08streamid\x18\x04 \x01(\x05\x12\x19\n\x05\x65rror\x18\x03 \x01(\x0b\x32\n.ErrorInfoB\x18\n\x16org.microg.gms.gcm.mcs') 22 | ) 23 | _sym_db.RegisterFileDescriptor(DESCRIPTOR) 24 | 25 | 26 | 27 | _LOGINREQUEST_AUTHSERVICE = _descriptor.EnumDescriptor( 28 | name='AuthService', 29 | full_name='LoginRequest.AuthService', 30 | filename=None, 31 | file=DESCRIPTOR, 32 | values=[ 33 | _descriptor.EnumValueDescriptor( 34 | name='ANDROID_ID', index=0, number=2, 35 | options=None, 36 | type=None), 37 | ], 38 | containing_type=None, 39 | options=None, 40 | serialized_start=886, 41 | serialized_end=915, 42 | ) 43 | _sym_db.RegisterEnumDescriptor(_LOGINREQUEST_AUTHSERVICE) 44 | 45 | _IQSTANZA_IQTYPE = _descriptor.EnumDescriptor( 46 | name='IqType', 47 | full_name='IqStanza.IqType', 48 | filename=None, 49 | file=DESCRIPTOR, 50 | values=[ 51 | _descriptor.EnumValueDescriptor( 52 | name='GET', index=0, number=0, 53 | options=None, 54 | type=None), 55 | _descriptor.EnumValueDescriptor( 56 | name='SET', index=1, number=1, 57 | options=None, 58 | type=None), 59 | _descriptor.EnumValueDescriptor( 60 | name='RESULT', index=2, number=2, 61 | options=None, 62 | type=None), 63 | _descriptor.EnumValueDescriptor( 64 | name='IQ_ERROR', index=3, number=3, 65 | options=None, 66 | type=None), 67 | ], 68 | containing_type=None, 69 | options=None, 70 | serialized_start=1501, 71 | serialized_end=1553, 72 | ) 73 | _sym_db.RegisterEnumDescriptor(_IQSTANZA_IQTYPE) 74 | 75 | 76 | _HEARTBEATPING = _descriptor.Descriptor( 77 | name='HeartbeatPing', 78 | full_name='HeartbeatPing', 79 | filename=None, 80 | file=DESCRIPTOR, 81 | containing_type=None, 82 | fields=[ 83 | _descriptor.FieldDescriptor( 84 | name='stream_id', full_name='HeartbeatPing.stream_id', index=0, 85 | number=1, type=5, cpp_type=1, label=1, 86 | has_default_value=False, default_value=0, 87 | message_type=None, enum_type=None, containing_type=None, 88 | is_extension=False, extension_scope=None, 89 | options=None), 90 | _descriptor.FieldDescriptor( 91 | name='last_stream_id_received', full_name='HeartbeatPing.last_stream_id_received', index=1, 92 | number=2, type=5, cpp_type=1, label=1, 93 | has_default_value=False, default_value=0, 94 | message_type=None, enum_type=None, containing_type=None, 95 | is_extension=False, extension_scope=None, 96 | options=None), 97 | _descriptor.FieldDescriptor( 98 | name='status', full_name='HeartbeatPing.status', index=2, 99 | number=3, type=3, cpp_type=2, label=1, 100 | has_default_value=False, default_value=0, 101 | message_type=None, enum_type=None, containing_type=None, 102 | is_extension=False, extension_scope=None, 103 | options=None), 104 | ], 105 | extensions=[ 106 | ], 107 | nested_types=[], 108 | enum_types=[ 109 | ], 110 | options=None, 111 | is_extendable=False, 112 | extension_ranges=[], 113 | oneofs=[ 114 | ], 115 | serialized_start=13, 116 | serialized_end=96, 117 | ) 118 | 119 | 120 | _HEARTBEATACK = _descriptor.Descriptor( 121 | name='HeartbeatAck', 122 | full_name='HeartbeatAck', 123 | filename=None, 124 | file=DESCRIPTOR, 125 | containing_type=None, 126 | fields=[ 127 | _descriptor.FieldDescriptor( 128 | name='stream_id', full_name='HeartbeatAck.stream_id', index=0, 129 | number=1, type=5, cpp_type=1, label=1, 130 | has_default_value=False, default_value=0, 131 | message_type=None, enum_type=None, containing_type=None, 132 | is_extension=False, extension_scope=None, 133 | options=None), 134 | _descriptor.FieldDescriptor( 135 | name='last_stream_id_received', full_name='HeartbeatAck.last_stream_id_received', index=1, 136 | number=2, type=5, cpp_type=1, label=1, 137 | has_default_value=False, default_value=0, 138 | message_type=None, enum_type=None, containing_type=None, 139 | is_extension=False, extension_scope=None, 140 | options=None), 141 | _descriptor.FieldDescriptor( 142 | name='status', full_name='HeartbeatAck.status', index=2, 143 | number=3, type=3, cpp_type=2, label=1, 144 | has_default_value=False, default_value=0, 145 | message_type=None, enum_type=None, containing_type=None, 146 | is_extension=False, extension_scope=None, 147 | options=None), 148 | ], 149 | extensions=[ 150 | ], 151 | nested_types=[], 152 | enum_types=[ 153 | ], 154 | options=None, 155 | is_extendable=False, 156 | extension_ranges=[], 157 | oneofs=[ 158 | ], 159 | serialized_start=98, 160 | serialized_end=180, 161 | ) 162 | 163 | 164 | _ERRORINFO = _descriptor.Descriptor( 165 | name='ErrorInfo', 166 | full_name='ErrorInfo', 167 | filename=None, 168 | file=DESCRIPTOR, 169 | containing_type=None, 170 | fields=[ 171 | _descriptor.FieldDescriptor( 172 | name='code', full_name='ErrorInfo.code', index=0, 173 | number=1, type=5, cpp_type=1, label=2, 174 | has_default_value=False, default_value=0, 175 | message_type=None, enum_type=None, containing_type=None, 176 | is_extension=False, extension_scope=None, 177 | options=None), 178 | _descriptor.FieldDescriptor( 179 | name='message', full_name='ErrorInfo.message', index=1, 180 | number=2, type=9, cpp_type=9, label=1, 181 | has_default_value=False, default_value=_b("").decode('utf-8'), 182 | message_type=None, enum_type=None, containing_type=None, 183 | is_extension=False, extension_scope=None, 184 | options=None), 185 | _descriptor.FieldDescriptor( 186 | name='type', full_name='ErrorInfo.type', index=2, 187 | number=3, type=9, cpp_type=9, label=1, 188 | has_default_value=False, default_value=_b("").decode('utf-8'), 189 | message_type=None, enum_type=None, containing_type=None, 190 | is_extension=False, extension_scope=None, 191 | options=None), 192 | _descriptor.FieldDescriptor( 193 | name='extension', full_name='ErrorInfo.extension', index=3, 194 | number=4, type=11, cpp_type=10, label=1, 195 | has_default_value=False, default_value=None, 196 | message_type=None, enum_type=None, containing_type=None, 197 | is_extension=False, extension_scope=None, 198 | options=None), 199 | ], 200 | extensions=[ 201 | ], 202 | nested_types=[], 203 | enum_types=[ 204 | ], 205 | options=None, 206 | is_extendable=False, 207 | extension_ranges=[], 208 | oneofs=[ 209 | ], 210 | serialized_start=182, 211 | serialized_end=269, 212 | ) 213 | 214 | 215 | _SETTING = _descriptor.Descriptor( 216 | name='Setting', 217 | full_name='Setting', 218 | filename=None, 219 | file=DESCRIPTOR, 220 | containing_type=None, 221 | fields=[ 222 | _descriptor.FieldDescriptor( 223 | name='name', full_name='Setting.name', index=0, 224 | number=1, type=9, cpp_type=9, label=2, 225 | has_default_value=False, default_value=_b("").decode('utf-8'), 226 | message_type=None, enum_type=None, containing_type=None, 227 | is_extension=False, extension_scope=None, 228 | options=None), 229 | _descriptor.FieldDescriptor( 230 | name='value', full_name='Setting.value', index=1, 231 | number=2, type=9, cpp_type=9, label=2, 232 | has_default_value=False, default_value=_b("").decode('utf-8'), 233 | message_type=None, enum_type=None, containing_type=None, 234 | is_extension=False, extension_scope=None, 235 | options=None), 236 | ], 237 | extensions=[ 238 | ], 239 | nested_types=[], 240 | enum_types=[ 241 | ], 242 | options=None, 243 | is_extendable=False, 244 | extension_ranges=[], 245 | oneofs=[ 246 | ], 247 | serialized_start=271, 248 | serialized_end=309, 249 | ) 250 | 251 | 252 | _HEARTBEATSTAT = _descriptor.Descriptor( 253 | name='HeartbeatStat', 254 | full_name='HeartbeatStat', 255 | filename=None, 256 | file=DESCRIPTOR, 257 | containing_type=None, 258 | fields=[ 259 | _descriptor.FieldDescriptor( 260 | name='ip', full_name='HeartbeatStat.ip', index=0, 261 | number=1, type=9, cpp_type=9, label=2, 262 | has_default_value=False, default_value=_b("").decode('utf-8'), 263 | message_type=None, enum_type=None, containing_type=None, 264 | is_extension=False, extension_scope=None, 265 | options=None), 266 | _descriptor.FieldDescriptor( 267 | name='timeout', full_name='HeartbeatStat.timeout', index=1, 268 | number=2, type=8, cpp_type=7, label=2, 269 | has_default_value=False, default_value=False, 270 | message_type=None, enum_type=None, containing_type=None, 271 | is_extension=False, extension_scope=None, 272 | options=None), 273 | _descriptor.FieldDescriptor( 274 | name='interval_ms', full_name='HeartbeatStat.interval_ms', index=2, 275 | number=3, type=5, cpp_type=1, label=2, 276 | has_default_value=False, default_value=0, 277 | message_type=None, enum_type=None, containing_type=None, 278 | is_extension=False, extension_scope=None, 279 | options=None), 280 | ], 281 | extensions=[ 282 | ], 283 | nested_types=[], 284 | enum_types=[ 285 | ], 286 | options=None, 287 | is_extendable=False, 288 | extension_ranges=[], 289 | oneofs=[ 290 | ], 291 | serialized_start=311, 292 | serialized_end=376, 293 | ) 294 | 295 | 296 | _HEARTBEATCONFIG = _descriptor.Descriptor( 297 | name='HeartbeatConfig', 298 | full_name='HeartbeatConfig', 299 | filename=None, 300 | file=DESCRIPTOR, 301 | containing_type=None, 302 | fields=[ 303 | _descriptor.FieldDescriptor( 304 | name='upload_stat', full_name='HeartbeatConfig.upload_stat', index=0, 305 | number=1, type=8, cpp_type=7, label=1, 306 | has_default_value=False, default_value=False, 307 | message_type=None, enum_type=None, containing_type=None, 308 | is_extension=False, extension_scope=None, 309 | options=None), 310 | _descriptor.FieldDescriptor( 311 | name='ip', full_name='HeartbeatConfig.ip', index=1, 312 | number=2, type=9, cpp_type=9, label=1, 313 | has_default_value=False, default_value=_b("").decode('utf-8'), 314 | message_type=None, enum_type=None, containing_type=None, 315 | is_extension=False, extension_scope=None, 316 | options=None), 317 | _descriptor.FieldDescriptor( 318 | name='interval_ms', full_name='HeartbeatConfig.interval_ms', index=2, 319 | number=3, type=5, cpp_type=1, label=1, 320 | has_default_value=False, default_value=0, 321 | message_type=None, enum_type=None, containing_type=None, 322 | is_extension=False, extension_scope=None, 323 | options=None), 324 | ], 325 | extensions=[ 326 | ], 327 | nested_types=[], 328 | enum_types=[ 329 | ], 330 | options=None, 331 | is_extendable=False, 332 | extension_ranges=[], 333 | oneofs=[ 334 | ], 335 | serialized_start=378, 336 | serialized_end=449, 337 | ) 338 | 339 | 340 | _LOGINREQUEST = _descriptor.Descriptor( 341 | name='LoginRequest', 342 | full_name='LoginRequest', 343 | filename=None, 344 | file=DESCRIPTOR, 345 | containing_type=None, 346 | fields=[ 347 | _descriptor.FieldDescriptor( 348 | name='id', full_name='LoginRequest.id', index=0, 349 | number=1, type=9, cpp_type=9, label=2, 350 | has_default_value=False, default_value=_b("").decode('utf-8'), 351 | message_type=None, enum_type=None, containing_type=None, 352 | is_extension=False, extension_scope=None, 353 | options=None), 354 | _descriptor.FieldDescriptor( 355 | name='domain', full_name='LoginRequest.domain', index=1, 356 | number=2, type=9, cpp_type=9, label=2, 357 | has_default_value=False, default_value=_b("").decode('utf-8'), 358 | message_type=None, enum_type=None, containing_type=None, 359 | is_extension=False, extension_scope=None, 360 | options=None), 361 | _descriptor.FieldDescriptor( 362 | name='user', full_name='LoginRequest.user', index=2, 363 | number=3, type=9, cpp_type=9, label=2, 364 | has_default_value=False, default_value=_b("").decode('utf-8'), 365 | message_type=None, enum_type=None, containing_type=None, 366 | is_extension=False, extension_scope=None, 367 | options=None), 368 | _descriptor.FieldDescriptor( 369 | name='resource', full_name='LoginRequest.resource', index=3, 370 | number=4, type=9, cpp_type=9, label=2, 371 | has_default_value=False, default_value=_b("").decode('utf-8'), 372 | message_type=None, enum_type=None, containing_type=None, 373 | is_extension=False, extension_scope=None, 374 | options=None), 375 | _descriptor.FieldDescriptor( 376 | name='auth_token', full_name='LoginRequest.auth_token', index=4, 377 | number=5, type=9, cpp_type=9, label=2, 378 | has_default_value=False, default_value=_b("").decode('utf-8'), 379 | message_type=None, enum_type=None, containing_type=None, 380 | is_extension=False, extension_scope=None, 381 | options=None), 382 | _descriptor.FieldDescriptor( 383 | name='device_id', full_name='LoginRequest.device_id', index=5, 384 | number=6, type=9, cpp_type=9, label=1, 385 | has_default_value=False, default_value=_b("").decode('utf-8'), 386 | message_type=None, enum_type=None, containing_type=None, 387 | is_extension=False, extension_scope=None, 388 | options=None), 389 | _descriptor.FieldDescriptor( 390 | name='last_rmq_id', full_name='LoginRequest.last_rmq_id', index=6, 391 | number=7, type=3, cpp_type=2, label=1, 392 | has_default_value=False, default_value=0, 393 | message_type=None, enum_type=None, containing_type=None, 394 | is_extension=False, extension_scope=None, 395 | options=None), 396 | _descriptor.FieldDescriptor( 397 | name='setting', full_name='LoginRequest.setting', index=7, 398 | number=8, type=11, cpp_type=10, label=3, 399 | has_default_value=False, default_value=[], 400 | message_type=None, enum_type=None, containing_type=None, 401 | is_extension=False, extension_scope=None, 402 | options=None), 403 | _descriptor.FieldDescriptor( 404 | name='compress', full_name='LoginRequest.compress', index=8, 405 | number=9, type=5, cpp_type=1, label=1, 406 | has_default_value=False, default_value=0, 407 | message_type=None, enum_type=None, containing_type=None, 408 | is_extension=False, extension_scope=None, 409 | options=None), 410 | _descriptor.FieldDescriptor( 411 | name='received_persistent_id', full_name='LoginRequest.received_persistent_id', index=9, 412 | number=10, type=9, cpp_type=9, label=3, 413 | has_default_value=False, default_value=[], 414 | message_type=None, enum_type=None, containing_type=None, 415 | is_extension=False, extension_scope=None, 416 | options=None), 417 | _descriptor.FieldDescriptor( 418 | name='include_stream_ids', full_name='LoginRequest.include_stream_ids', index=10, 419 | number=11, type=8, cpp_type=7, label=1, 420 | has_default_value=False, default_value=False, 421 | message_type=None, enum_type=None, containing_type=None, 422 | is_extension=False, extension_scope=None, 423 | options=None), 424 | _descriptor.FieldDescriptor( 425 | name='adaptive_heartbeat', full_name='LoginRequest.adaptive_heartbeat', index=11, 426 | number=12, type=8, cpp_type=7, label=1, 427 | has_default_value=False, default_value=False, 428 | message_type=None, enum_type=None, containing_type=None, 429 | is_extension=False, extension_scope=None, 430 | options=None), 431 | _descriptor.FieldDescriptor( 432 | name='heartbeat_stat', full_name='LoginRequest.heartbeat_stat', index=12, 433 | number=13, type=11, cpp_type=10, label=1, 434 | has_default_value=False, default_value=None, 435 | message_type=None, enum_type=None, containing_type=None, 436 | is_extension=False, extension_scope=None, 437 | options=None), 438 | _descriptor.FieldDescriptor( 439 | name='use_rmq2', full_name='LoginRequest.use_rmq2', index=13, 440 | number=14, type=8, cpp_type=7, label=1, 441 | has_default_value=False, default_value=False, 442 | message_type=None, enum_type=None, containing_type=None, 443 | is_extension=False, extension_scope=None, 444 | options=None), 445 | _descriptor.FieldDescriptor( 446 | name='account_id', full_name='LoginRequest.account_id', index=14, 447 | number=15, type=3, cpp_type=2, label=1, 448 | has_default_value=False, default_value=0, 449 | message_type=None, enum_type=None, containing_type=None, 450 | is_extension=False, extension_scope=None, 451 | options=None), 452 | _descriptor.FieldDescriptor( 453 | name='auth_service', full_name='LoginRequest.auth_service', index=15, 454 | number=16, type=14, cpp_type=8, label=1, 455 | has_default_value=False, default_value=2, 456 | message_type=None, enum_type=None, containing_type=None, 457 | is_extension=False, extension_scope=None, 458 | options=None), 459 | _descriptor.FieldDescriptor( 460 | name='network_type', full_name='LoginRequest.network_type', index=16, 461 | number=17, type=5, cpp_type=1, label=1, 462 | has_default_value=False, default_value=0, 463 | message_type=None, enum_type=None, containing_type=None, 464 | is_extension=False, extension_scope=None, 465 | options=None), 466 | _descriptor.FieldDescriptor( 467 | name='status', full_name='LoginRequest.status', index=17, 468 | number=18, type=3, cpp_type=2, label=1, 469 | has_default_value=False, default_value=0, 470 | message_type=None, enum_type=None, containing_type=None, 471 | is_extension=False, extension_scope=None, 472 | options=None), 473 | ], 474 | extensions=[ 475 | ], 476 | nested_types=[], 477 | enum_types=[ 478 | _LOGINREQUEST_AUTHSERVICE, 479 | ], 480 | options=None, 481 | is_extendable=False, 482 | extension_ranges=[], 483 | oneofs=[ 484 | ], 485 | serialized_start=452, 486 | serialized_end=915, 487 | ) 488 | 489 | 490 | _LOGINRESPONSE = _descriptor.Descriptor( 491 | name='LoginResponse', 492 | full_name='LoginResponse', 493 | filename=None, 494 | file=DESCRIPTOR, 495 | containing_type=None, 496 | fields=[ 497 | _descriptor.FieldDescriptor( 498 | name='id', full_name='LoginResponse.id', index=0, 499 | number=1, type=9, cpp_type=9, label=2, 500 | has_default_value=False, default_value=_b("").decode('utf-8'), 501 | message_type=None, enum_type=None, containing_type=None, 502 | is_extension=False, extension_scope=None, 503 | options=None), 504 | _descriptor.FieldDescriptor( 505 | name='jid', full_name='LoginResponse.jid', index=1, 506 | number=2, type=9, cpp_type=9, label=1, 507 | has_default_value=False, default_value=_b("").decode('utf-8'), 508 | message_type=None, enum_type=None, containing_type=None, 509 | is_extension=False, extension_scope=None, 510 | options=None), 511 | _descriptor.FieldDescriptor( 512 | name='error', full_name='LoginResponse.error', index=2, 513 | number=3, type=11, cpp_type=10, label=1, 514 | has_default_value=False, default_value=None, 515 | message_type=None, enum_type=None, containing_type=None, 516 | is_extension=False, extension_scope=None, 517 | options=None), 518 | _descriptor.FieldDescriptor( 519 | name='setting', full_name='LoginResponse.setting', index=3, 520 | number=4, type=11, cpp_type=10, label=3, 521 | has_default_value=False, default_value=[], 522 | message_type=None, enum_type=None, containing_type=None, 523 | is_extension=False, extension_scope=None, 524 | options=None), 525 | _descriptor.FieldDescriptor( 526 | name='stream_id', full_name='LoginResponse.stream_id', index=4, 527 | number=5, type=5, cpp_type=1, label=1, 528 | has_default_value=False, default_value=0, 529 | message_type=None, enum_type=None, containing_type=None, 530 | is_extension=False, extension_scope=None, 531 | options=None), 532 | _descriptor.FieldDescriptor( 533 | name='last_stream_id_received', full_name='LoginResponse.last_stream_id_received', index=5, 534 | number=6, type=5, cpp_type=1, label=1, 535 | has_default_value=False, default_value=0, 536 | message_type=None, enum_type=None, containing_type=None, 537 | is_extension=False, extension_scope=None, 538 | options=None), 539 | _descriptor.FieldDescriptor( 540 | name='heartbeat_config', full_name='LoginResponse.heartbeat_config', index=6, 541 | number=7, type=11, cpp_type=10, label=1, 542 | has_default_value=False, default_value=None, 543 | message_type=None, enum_type=None, containing_type=None, 544 | is_extension=False, extension_scope=None, 545 | options=None), 546 | _descriptor.FieldDescriptor( 547 | name='server_timestamp', full_name='LoginResponse.server_timestamp', index=7, 548 | number=8, type=3, cpp_type=2, label=1, 549 | has_default_value=False, default_value=0, 550 | message_type=None, enum_type=None, containing_type=None, 551 | is_extension=False, extension_scope=None, 552 | options=None), 553 | ], 554 | extensions=[ 555 | ], 556 | nested_types=[], 557 | enum_types=[ 558 | ], 559 | options=None, 560 | is_extendable=False, 561 | extension_ranges=[], 562 | oneofs=[ 563 | ], 564 | serialized_start=918, 565 | serialized_end=1134, 566 | ) 567 | 568 | 569 | _STREAMERRORSTANZA = _descriptor.Descriptor( 570 | name='StreamErrorStanza', 571 | full_name='StreamErrorStanza', 572 | filename=None, 573 | file=DESCRIPTOR, 574 | containing_type=None, 575 | fields=[ 576 | _descriptor.FieldDescriptor( 577 | name='type', full_name='StreamErrorStanza.type', index=0, 578 | number=1, type=9, cpp_type=9, label=2, 579 | has_default_value=False, default_value=_b("").decode('utf-8'), 580 | message_type=None, enum_type=None, containing_type=None, 581 | is_extension=False, extension_scope=None, 582 | options=None), 583 | _descriptor.FieldDescriptor( 584 | name='text', full_name='StreamErrorStanza.text', index=1, 585 | number=2, type=9, cpp_type=9, label=1, 586 | has_default_value=False, default_value=_b("").decode('utf-8'), 587 | message_type=None, enum_type=None, containing_type=None, 588 | is_extension=False, extension_scope=None, 589 | options=None), 590 | ], 591 | extensions=[ 592 | ], 593 | nested_types=[], 594 | enum_types=[ 595 | ], 596 | options=None, 597 | is_extendable=False, 598 | extension_ranges=[], 599 | oneofs=[ 600 | ], 601 | serialized_start=1136, 602 | serialized_end=1183, 603 | ) 604 | 605 | 606 | _CLOSE = _descriptor.Descriptor( 607 | name='Close', 608 | full_name='Close', 609 | filename=None, 610 | file=DESCRIPTOR, 611 | containing_type=None, 612 | fields=[ 613 | ], 614 | extensions=[ 615 | ], 616 | nested_types=[], 617 | enum_types=[ 618 | ], 619 | options=None, 620 | is_extendable=False, 621 | extension_ranges=[], 622 | oneofs=[ 623 | ], 624 | serialized_start=1185, 625 | serialized_end=1192, 626 | ) 627 | 628 | 629 | _EXTENSION = _descriptor.Descriptor( 630 | name='Extension', 631 | full_name='Extension', 632 | filename=None, 633 | file=DESCRIPTOR, 634 | containing_type=None, 635 | fields=[ 636 | _descriptor.FieldDescriptor( 637 | name='id', full_name='Extension.id', index=0, 638 | number=1, type=5, cpp_type=1, label=2, 639 | has_default_value=False, default_value=0, 640 | message_type=None, enum_type=None, containing_type=None, 641 | is_extension=False, extension_scope=None, 642 | options=None), 643 | _descriptor.FieldDescriptor( 644 | name='data', full_name='Extension.data', index=1, 645 | number=2, type=12, cpp_type=9, label=2, 646 | has_default_value=False, default_value=_b(""), 647 | message_type=None, enum_type=None, containing_type=None, 648 | is_extension=False, extension_scope=None, 649 | options=None), 650 | ], 651 | extensions=[ 652 | ], 653 | nested_types=[], 654 | enum_types=[ 655 | ], 656 | options=None, 657 | is_extendable=False, 658 | extension_ranges=[], 659 | oneofs=[ 660 | ], 661 | serialized_start=1194, 662 | serialized_end=1231, 663 | ) 664 | 665 | 666 | _IQSTANZA = _descriptor.Descriptor( 667 | name='IqStanza', 668 | full_name='IqStanza', 669 | filename=None, 670 | file=DESCRIPTOR, 671 | containing_type=None, 672 | fields=[ 673 | _descriptor.FieldDescriptor( 674 | name='rmq_id', full_name='IqStanza.rmq_id', index=0, 675 | number=1, type=3, cpp_type=2, label=1, 676 | has_default_value=False, default_value=0, 677 | message_type=None, enum_type=None, containing_type=None, 678 | is_extension=False, extension_scope=None, 679 | options=None), 680 | _descriptor.FieldDescriptor( 681 | name='type', full_name='IqStanza.type', index=1, 682 | number=2, type=14, cpp_type=8, label=2, 683 | has_default_value=False, default_value=0, 684 | message_type=None, enum_type=None, containing_type=None, 685 | is_extension=False, extension_scope=None, 686 | options=None), 687 | _descriptor.FieldDescriptor( 688 | name='id', full_name='IqStanza.id', index=2, 689 | number=3, type=9, cpp_type=9, label=2, 690 | has_default_value=False, default_value=_b("").decode('utf-8'), 691 | message_type=None, enum_type=None, containing_type=None, 692 | is_extension=False, extension_scope=None, 693 | options=None), 694 | _descriptor.FieldDescriptor( 695 | name='from', full_name='IqStanza.from', index=3, 696 | number=4, type=9, cpp_type=9, label=1, 697 | has_default_value=False, default_value=_b("").decode('utf-8'), 698 | message_type=None, enum_type=None, containing_type=None, 699 | is_extension=False, extension_scope=None, 700 | options=None), 701 | _descriptor.FieldDescriptor( 702 | name='to', full_name='IqStanza.to', index=4, 703 | number=5, type=9, cpp_type=9, label=1, 704 | has_default_value=False, default_value=_b("").decode('utf-8'), 705 | message_type=None, enum_type=None, containing_type=None, 706 | is_extension=False, extension_scope=None, 707 | options=None), 708 | _descriptor.FieldDescriptor( 709 | name='error', full_name='IqStanza.error', index=5, 710 | number=6, type=11, cpp_type=10, label=1, 711 | has_default_value=False, default_value=None, 712 | message_type=None, enum_type=None, containing_type=None, 713 | is_extension=False, extension_scope=None, 714 | options=None), 715 | _descriptor.FieldDescriptor( 716 | name='extension', full_name='IqStanza.extension', index=6, 717 | number=7, type=11, cpp_type=10, label=1, 718 | has_default_value=False, default_value=None, 719 | message_type=None, enum_type=None, containing_type=None, 720 | is_extension=False, extension_scope=None, 721 | options=None), 722 | _descriptor.FieldDescriptor( 723 | name='persistent_id', full_name='IqStanza.persistent_id', index=7, 724 | number=8, type=9, cpp_type=9, label=1, 725 | has_default_value=False, default_value=_b("").decode('utf-8'), 726 | message_type=None, enum_type=None, containing_type=None, 727 | is_extension=False, extension_scope=None, 728 | options=None), 729 | _descriptor.FieldDescriptor( 730 | name='stream_id', full_name='IqStanza.stream_id', index=8, 731 | number=9, type=5, cpp_type=1, label=1, 732 | has_default_value=False, default_value=0, 733 | message_type=None, enum_type=None, containing_type=None, 734 | is_extension=False, extension_scope=None, 735 | options=None), 736 | _descriptor.FieldDescriptor( 737 | name='last_stream_id_received', full_name='IqStanza.last_stream_id_received', index=9, 738 | number=10, type=5, cpp_type=1, label=1, 739 | has_default_value=False, default_value=0, 740 | message_type=None, enum_type=None, containing_type=None, 741 | is_extension=False, extension_scope=None, 742 | options=None), 743 | _descriptor.FieldDescriptor( 744 | name='account_id', full_name='IqStanza.account_id', index=10, 745 | number=11, type=3, cpp_type=2, label=1, 746 | has_default_value=False, default_value=0, 747 | message_type=None, enum_type=None, containing_type=None, 748 | is_extension=False, extension_scope=None, 749 | options=None), 750 | _descriptor.FieldDescriptor( 751 | name='status', full_name='IqStanza.status', index=11, 752 | number=12, type=3, cpp_type=2, label=1, 753 | has_default_value=False, default_value=0, 754 | message_type=None, enum_type=None, containing_type=None, 755 | is_extension=False, extension_scope=None, 756 | options=None), 757 | ], 758 | extensions=[ 759 | ], 760 | nested_types=[], 761 | enum_types=[ 762 | _IQSTANZA_IQTYPE, 763 | ], 764 | options=None, 765 | is_extendable=False, 766 | extension_ranges=[], 767 | oneofs=[ 768 | ], 769 | serialized_start=1234, 770 | serialized_end=1553, 771 | ) 772 | 773 | 774 | _APPDATA = _descriptor.Descriptor( 775 | name='AppData', 776 | full_name='AppData', 777 | filename=None, 778 | file=DESCRIPTOR, 779 | containing_type=None, 780 | fields=[ 781 | _descriptor.FieldDescriptor( 782 | name='key', full_name='AppData.key', index=0, 783 | number=1, type=9, cpp_type=9, label=2, 784 | has_default_value=False, default_value=_b("").decode('utf-8'), 785 | message_type=None, enum_type=None, containing_type=None, 786 | is_extension=False, extension_scope=None, 787 | options=None), 788 | _descriptor.FieldDescriptor( 789 | name='value', full_name='AppData.value', index=1, 790 | number=2, type=9, cpp_type=9, label=2, 791 | has_default_value=False, default_value=_b("").decode('utf-8'), 792 | message_type=None, enum_type=None, containing_type=None, 793 | is_extension=False, extension_scope=None, 794 | options=None), 795 | ], 796 | extensions=[ 797 | ], 798 | nested_types=[], 799 | enum_types=[ 800 | ], 801 | options=None, 802 | is_extendable=False, 803 | extension_ranges=[], 804 | oneofs=[ 805 | ], 806 | serialized_start=1555, 807 | serialized_end=1592, 808 | ) 809 | 810 | 811 | _DATAMESSAGESTANZA = _descriptor.Descriptor( 812 | name='DataMessageStanza', 813 | full_name='DataMessageStanza', 814 | filename=None, 815 | file=DESCRIPTOR, 816 | containing_type=None, 817 | fields=[ 818 | _descriptor.FieldDescriptor( 819 | name='rmq_id', full_name='DataMessageStanza.rmq_id', index=0, 820 | number=1, type=3, cpp_type=2, label=1, 821 | has_default_value=False, default_value=0, 822 | message_type=None, enum_type=None, containing_type=None, 823 | is_extension=False, extension_scope=None, 824 | options=None), 825 | _descriptor.FieldDescriptor( 826 | name='id', full_name='DataMessageStanza.id', index=1, 827 | number=2, type=9, cpp_type=9, label=1, 828 | has_default_value=False, default_value=_b("").decode('utf-8'), 829 | message_type=None, enum_type=None, containing_type=None, 830 | is_extension=False, extension_scope=None, 831 | options=None), 832 | _descriptor.FieldDescriptor( 833 | name='from', full_name='DataMessageStanza.from', index=2, 834 | number=3, type=9, cpp_type=9, label=2, 835 | has_default_value=False, default_value=_b("").decode('utf-8'), 836 | message_type=None, enum_type=None, containing_type=None, 837 | is_extension=False, extension_scope=None, 838 | options=None), 839 | _descriptor.FieldDescriptor( 840 | name='to', full_name='DataMessageStanza.to', index=3, 841 | number=4, type=9, cpp_type=9, label=1, 842 | has_default_value=False, default_value=_b("").decode('utf-8'), 843 | message_type=None, enum_type=None, containing_type=None, 844 | is_extension=False, extension_scope=None, 845 | options=None), 846 | _descriptor.FieldDescriptor( 847 | name='category', full_name='DataMessageStanza.category', index=4, 848 | number=5, type=9, cpp_type=9, label=2, 849 | has_default_value=False, default_value=_b("").decode('utf-8'), 850 | message_type=None, enum_type=None, containing_type=None, 851 | is_extension=False, extension_scope=None, 852 | options=None), 853 | _descriptor.FieldDescriptor( 854 | name='token', full_name='DataMessageStanza.token', index=5, 855 | number=6, type=9, cpp_type=9, label=1, 856 | has_default_value=False, default_value=_b("").decode('utf-8'), 857 | message_type=None, enum_type=None, containing_type=None, 858 | is_extension=False, extension_scope=None, 859 | options=None), 860 | _descriptor.FieldDescriptor( 861 | name='app_data', full_name='DataMessageStanza.app_data', index=6, 862 | number=7, type=11, cpp_type=10, label=3, 863 | has_default_value=False, default_value=[], 864 | message_type=None, enum_type=None, containing_type=None, 865 | is_extension=False, extension_scope=None, 866 | options=None), 867 | _descriptor.FieldDescriptor( 868 | name='from_trusted_server', full_name='DataMessageStanza.from_trusted_server', index=7, 869 | number=8, type=8, cpp_type=7, label=1, 870 | has_default_value=False, default_value=False, 871 | message_type=None, enum_type=None, containing_type=None, 872 | is_extension=False, extension_scope=None, 873 | options=None), 874 | _descriptor.FieldDescriptor( 875 | name='persistent_id', full_name='DataMessageStanza.persistent_id', index=8, 876 | number=9, type=9, cpp_type=9, label=1, 877 | has_default_value=False, default_value=_b("").decode('utf-8'), 878 | message_type=None, enum_type=None, containing_type=None, 879 | is_extension=False, extension_scope=None, 880 | options=None), 881 | _descriptor.FieldDescriptor( 882 | name='stream_id', full_name='DataMessageStanza.stream_id', index=9, 883 | number=10, type=5, cpp_type=1, label=1, 884 | has_default_value=False, default_value=0, 885 | message_type=None, enum_type=None, containing_type=None, 886 | is_extension=False, extension_scope=None, 887 | options=None), 888 | _descriptor.FieldDescriptor( 889 | name='last_stream_id_received', full_name='DataMessageStanza.last_stream_id_received', index=10, 890 | number=11, type=5, cpp_type=1, label=1, 891 | has_default_value=False, default_value=0, 892 | message_type=None, enum_type=None, containing_type=None, 893 | is_extension=False, extension_scope=None, 894 | options=None), 895 | _descriptor.FieldDescriptor( 896 | name='permission', full_name='DataMessageStanza.permission', index=11, 897 | number=12, type=9, cpp_type=9, label=1, 898 | has_default_value=False, default_value=_b("").decode('utf-8'), 899 | message_type=None, enum_type=None, containing_type=None, 900 | is_extension=False, extension_scope=None, 901 | options=None), 902 | _descriptor.FieldDescriptor( 903 | name='reg_id', full_name='DataMessageStanza.reg_id', index=12, 904 | number=13, type=9, cpp_type=9, label=1, 905 | has_default_value=False, default_value=_b("").decode('utf-8'), 906 | message_type=None, enum_type=None, containing_type=None, 907 | is_extension=False, extension_scope=None, 908 | options=None), 909 | _descriptor.FieldDescriptor( 910 | name='pkg_signature', full_name='DataMessageStanza.pkg_signature', index=13, 911 | number=14, type=9, cpp_type=9, label=1, 912 | has_default_value=False, default_value=_b("").decode('utf-8'), 913 | message_type=None, enum_type=None, containing_type=None, 914 | is_extension=False, extension_scope=None, 915 | options=None), 916 | _descriptor.FieldDescriptor( 917 | name='client_id', full_name='DataMessageStanza.client_id', index=14, 918 | number=15, type=9, cpp_type=9, label=1, 919 | has_default_value=False, default_value=_b("").decode('utf-8'), 920 | message_type=None, enum_type=None, containing_type=None, 921 | is_extension=False, extension_scope=None, 922 | options=None), 923 | _descriptor.FieldDescriptor( 924 | name='device_user_id', full_name='DataMessageStanza.device_user_id', index=15, 925 | number=16, type=3, cpp_type=2, label=1, 926 | has_default_value=False, default_value=0, 927 | message_type=None, enum_type=None, containing_type=None, 928 | is_extension=False, extension_scope=None, 929 | options=None), 930 | _descriptor.FieldDescriptor( 931 | name='ttl', full_name='DataMessageStanza.ttl', index=16, 932 | number=17, type=5, cpp_type=1, label=1, 933 | has_default_value=False, default_value=0, 934 | message_type=None, enum_type=None, containing_type=None, 935 | is_extension=False, extension_scope=None, 936 | options=None), 937 | _descriptor.FieldDescriptor( 938 | name='sent', full_name='DataMessageStanza.sent', index=17, 939 | number=18, type=3, cpp_type=2, label=1, 940 | has_default_value=False, default_value=0, 941 | message_type=None, enum_type=None, containing_type=None, 942 | is_extension=False, extension_scope=None, 943 | options=None), 944 | _descriptor.FieldDescriptor( 945 | name='queued', full_name='DataMessageStanza.queued', index=18, 946 | number=19, type=5, cpp_type=1, label=1, 947 | has_default_value=False, default_value=0, 948 | message_type=None, enum_type=None, containing_type=None, 949 | is_extension=False, extension_scope=None, 950 | options=None), 951 | _descriptor.FieldDescriptor( 952 | name='status', full_name='DataMessageStanza.status', index=19, 953 | number=20, type=3, cpp_type=2, label=1, 954 | has_default_value=False, default_value=0, 955 | message_type=None, enum_type=None, containing_type=None, 956 | is_extension=False, extension_scope=None, 957 | options=None), 958 | _descriptor.FieldDescriptor( 959 | name='raw_data', full_name='DataMessageStanza.raw_data', index=20, 960 | number=21, type=12, cpp_type=9, label=1, 961 | has_default_value=False, default_value=_b(""), 962 | message_type=None, enum_type=None, containing_type=None, 963 | is_extension=False, extension_scope=None, 964 | options=None), 965 | _descriptor.FieldDescriptor( 966 | name='delay', full_name='DataMessageStanza.delay', index=21, 967 | number=22, type=5, cpp_type=1, label=1, 968 | has_default_value=False, default_value=0, 969 | message_type=None, enum_type=None, containing_type=None, 970 | is_extension=False, extension_scope=None, 971 | options=None), 972 | ], 973 | extensions=[ 974 | ], 975 | nested_types=[], 976 | enum_types=[ 977 | ], 978 | options=None, 979 | is_extendable=False, 980 | extension_ranges=[], 981 | oneofs=[ 982 | ], 983 | serialized_start=1595, 984 | serialized_end=2027, 985 | ) 986 | 987 | 988 | _STREAMACK = _descriptor.Descriptor( 989 | name='StreamAck', 990 | full_name='StreamAck', 991 | filename=None, 992 | file=DESCRIPTOR, 993 | containing_type=None, 994 | fields=[ 995 | ], 996 | extensions=[ 997 | ], 998 | nested_types=[], 999 | enum_types=[ 1000 | ], 1001 | options=None, 1002 | is_extendable=False, 1003 | extension_ranges=[], 1004 | oneofs=[ 1005 | ], 1006 | serialized_start=2029, 1007 | serialized_end=2040, 1008 | ) 1009 | 1010 | 1011 | _SELECTIVEACK = _descriptor.Descriptor( 1012 | name='SelectiveAck', 1013 | full_name='SelectiveAck', 1014 | filename=None, 1015 | file=DESCRIPTOR, 1016 | containing_type=None, 1017 | fields=[ 1018 | _descriptor.FieldDescriptor( 1019 | name='id', full_name='SelectiveAck.id', index=0, 1020 | number=1, type=9, cpp_type=9, label=3, 1021 | has_default_value=False, default_value=[], 1022 | message_type=None, enum_type=None, containing_type=None, 1023 | is_extension=False, extension_scope=None, 1024 | options=None), 1025 | ], 1026 | extensions=[ 1027 | ], 1028 | nested_types=[], 1029 | enum_types=[ 1030 | ], 1031 | options=None, 1032 | is_extendable=False, 1033 | extension_ranges=[], 1034 | oneofs=[ 1035 | ], 1036 | serialized_start=2042, 1037 | serialized_end=2068, 1038 | ) 1039 | 1040 | 1041 | _BINDACCOUNTREQUEST = _descriptor.Descriptor( 1042 | name='BindAccountRequest', 1043 | full_name='BindAccountRequest', 1044 | filename=None, 1045 | file=DESCRIPTOR, 1046 | containing_type=None, 1047 | fields=[ 1048 | _descriptor.FieldDescriptor( 1049 | name='packetid', full_name='BindAccountRequest.packetid', index=0, 1050 | number=1, type=9, cpp_type=9, label=1, 1051 | has_default_value=False, default_value=_b("").decode('utf-8'), 1052 | message_type=None, enum_type=None, containing_type=None, 1053 | is_extension=False, extension_scope=None, 1054 | options=None), 1055 | _descriptor.FieldDescriptor( 1056 | name='domain', full_name='BindAccountRequest.domain', index=1, 1057 | number=2, type=9, cpp_type=9, label=1, 1058 | has_default_value=False, default_value=_b("").decode('utf-8'), 1059 | message_type=None, enum_type=None, containing_type=None, 1060 | is_extension=False, extension_scope=None, 1061 | options=None), 1062 | _descriptor.FieldDescriptor( 1063 | name='user', full_name='BindAccountRequest.user', index=2, 1064 | number=3, type=9, cpp_type=9, label=1, 1065 | has_default_value=False, default_value=_b("").decode('utf-8'), 1066 | message_type=None, enum_type=None, containing_type=None, 1067 | is_extension=False, extension_scope=None, 1068 | options=None), 1069 | _descriptor.FieldDescriptor( 1070 | name='resource', full_name='BindAccountRequest.resource', index=3, 1071 | number=4, type=9, cpp_type=9, label=1, 1072 | has_default_value=False, default_value=_b("").decode('utf-8'), 1073 | message_type=None, enum_type=None, containing_type=None, 1074 | is_extension=False, extension_scope=None, 1075 | options=None), 1076 | _descriptor.FieldDescriptor( 1077 | name='accountid', full_name='BindAccountRequest.accountid', index=4, 1078 | number=9, type=3, cpp_type=2, label=1, 1079 | has_default_value=False, default_value=0, 1080 | message_type=None, enum_type=None, containing_type=None, 1081 | is_extension=False, extension_scope=None, 1082 | options=None), 1083 | _descriptor.FieldDescriptor( 1084 | name='token', full_name='BindAccountRequest.token', index=5, 1085 | number=5, type=9, cpp_type=9, label=1, 1086 | has_default_value=False, default_value=_b("").decode('utf-8'), 1087 | message_type=None, enum_type=None, containing_type=None, 1088 | is_extension=False, extension_scope=None, 1089 | options=None), 1090 | ], 1091 | extensions=[ 1092 | ], 1093 | nested_types=[], 1094 | enum_types=[ 1095 | ], 1096 | options=None, 1097 | is_extendable=False, 1098 | extension_ranges=[], 1099 | oneofs=[ 1100 | ], 1101 | serialized_start=2070, 1102 | serialized_end=2190, 1103 | ) 1104 | 1105 | 1106 | _BINDACCOUNTRESPONSE = _descriptor.Descriptor( 1107 | name='BindAccountResponse', 1108 | full_name='BindAccountResponse', 1109 | filename=None, 1110 | file=DESCRIPTOR, 1111 | containing_type=None, 1112 | fields=[ 1113 | _descriptor.FieldDescriptor( 1114 | name='packetid', full_name='BindAccountResponse.packetid', index=0, 1115 | number=1, type=9, cpp_type=9, label=1, 1116 | has_default_value=False, default_value=_b("").decode('utf-8'), 1117 | message_type=None, enum_type=None, containing_type=None, 1118 | is_extension=False, extension_scope=None, 1119 | options=None), 1120 | _descriptor.FieldDescriptor( 1121 | name='jid', full_name='BindAccountResponse.jid', index=1, 1122 | number=2, type=9, cpp_type=9, label=1, 1123 | has_default_value=False, default_value=_b("").decode('utf-8'), 1124 | message_type=None, enum_type=None, containing_type=None, 1125 | is_extension=False, extension_scope=None, 1126 | options=None), 1127 | _descriptor.FieldDescriptor( 1128 | name='laststreamid', full_name='BindAccountResponse.laststreamid', index=2, 1129 | number=5, type=5, cpp_type=1, label=1, 1130 | has_default_value=False, default_value=0, 1131 | message_type=None, enum_type=None, containing_type=None, 1132 | is_extension=False, extension_scope=None, 1133 | options=None), 1134 | _descriptor.FieldDescriptor( 1135 | name='streamid', full_name='BindAccountResponse.streamid', index=3, 1136 | number=4, type=5, cpp_type=1, label=1, 1137 | has_default_value=False, default_value=0, 1138 | message_type=None, enum_type=None, containing_type=None, 1139 | is_extension=False, extension_scope=None, 1140 | options=None), 1141 | _descriptor.FieldDescriptor( 1142 | name='error', full_name='BindAccountResponse.error', index=4, 1143 | number=3, type=11, cpp_type=10, label=1, 1144 | has_default_value=False, default_value=None, 1145 | message_type=None, enum_type=None, containing_type=None, 1146 | is_extension=False, extension_scope=None, 1147 | options=None), 1148 | ], 1149 | extensions=[ 1150 | ], 1151 | nested_types=[], 1152 | enum_types=[ 1153 | ], 1154 | options=None, 1155 | is_extendable=False, 1156 | extension_ranges=[], 1157 | oneofs=[ 1158 | ], 1159 | serialized_start=2192, 1160 | serialized_end=2311, 1161 | ) 1162 | 1163 | _ERRORINFO.fields_by_name['extension'].message_type = _EXTENSION 1164 | _LOGINREQUEST.fields_by_name['setting'].message_type = _SETTING 1165 | _LOGINREQUEST.fields_by_name['heartbeat_stat'].message_type = _HEARTBEATSTAT 1166 | _LOGINREQUEST.fields_by_name['auth_service'].enum_type = _LOGINREQUEST_AUTHSERVICE 1167 | _LOGINREQUEST_AUTHSERVICE.containing_type = _LOGINREQUEST 1168 | _LOGINRESPONSE.fields_by_name['error'].message_type = _ERRORINFO 1169 | _LOGINRESPONSE.fields_by_name['setting'].message_type = _SETTING 1170 | _LOGINRESPONSE.fields_by_name['heartbeat_config'].message_type = _HEARTBEATCONFIG 1171 | _IQSTANZA.fields_by_name['type'].enum_type = _IQSTANZA_IQTYPE 1172 | _IQSTANZA.fields_by_name['error'].message_type = _ERRORINFO 1173 | _IQSTANZA.fields_by_name['extension'].message_type = _EXTENSION 1174 | _IQSTANZA_IQTYPE.containing_type = _IQSTANZA 1175 | _DATAMESSAGESTANZA.fields_by_name['app_data'].message_type = _APPDATA 1176 | _BINDACCOUNTRESPONSE.fields_by_name['error'].message_type = _ERRORINFO 1177 | DESCRIPTOR.message_types_by_name['HeartbeatPing'] = _HEARTBEATPING 1178 | DESCRIPTOR.message_types_by_name['HeartbeatAck'] = _HEARTBEATACK 1179 | DESCRIPTOR.message_types_by_name['ErrorInfo'] = _ERRORINFO 1180 | DESCRIPTOR.message_types_by_name['Setting'] = _SETTING 1181 | DESCRIPTOR.message_types_by_name['HeartbeatStat'] = _HEARTBEATSTAT 1182 | DESCRIPTOR.message_types_by_name['HeartbeatConfig'] = _HEARTBEATCONFIG 1183 | DESCRIPTOR.message_types_by_name['LoginRequest'] = _LOGINREQUEST 1184 | DESCRIPTOR.message_types_by_name['LoginResponse'] = _LOGINRESPONSE 1185 | DESCRIPTOR.message_types_by_name['StreamErrorStanza'] = _STREAMERRORSTANZA 1186 | DESCRIPTOR.message_types_by_name['Close'] = _CLOSE 1187 | DESCRIPTOR.message_types_by_name['Extension'] = _EXTENSION 1188 | DESCRIPTOR.message_types_by_name['IqStanza'] = _IQSTANZA 1189 | DESCRIPTOR.message_types_by_name['AppData'] = _APPDATA 1190 | DESCRIPTOR.message_types_by_name['DataMessageStanza'] = _DATAMESSAGESTANZA 1191 | DESCRIPTOR.message_types_by_name['StreamAck'] = _STREAMACK 1192 | DESCRIPTOR.message_types_by_name['SelectiveAck'] = _SELECTIVEACK 1193 | DESCRIPTOR.message_types_by_name['BindAccountRequest'] = _BINDACCOUNTREQUEST 1194 | DESCRIPTOR.message_types_by_name['BindAccountResponse'] = _BINDACCOUNTRESPONSE 1195 | 1196 | HeartbeatPing = _reflection.GeneratedProtocolMessageType('HeartbeatPing', (_message.Message,), dict( 1197 | DESCRIPTOR = _HEARTBEATPING, 1198 | __module__ = 'mcs_pb2' 1199 | # @@protoc_insertion_point(class_scope:HeartbeatPing) 1200 | )) 1201 | _sym_db.RegisterMessage(HeartbeatPing) 1202 | 1203 | HeartbeatAck = _reflection.GeneratedProtocolMessageType('HeartbeatAck', (_message.Message,), dict( 1204 | DESCRIPTOR = _HEARTBEATACK, 1205 | __module__ = 'mcs_pb2' 1206 | # @@protoc_insertion_point(class_scope:HeartbeatAck) 1207 | )) 1208 | _sym_db.RegisterMessage(HeartbeatAck) 1209 | 1210 | ErrorInfo = _reflection.GeneratedProtocolMessageType('ErrorInfo', (_message.Message,), dict( 1211 | DESCRIPTOR = _ERRORINFO, 1212 | __module__ = 'mcs_pb2' 1213 | # @@protoc_insertion_point(class_scope:ErrorInfo) 1214 | )) 1215 | _sym_db.RegisterMessage(ErrorInfo) 1216 | 1217 | Setting = _reflection.GeneratedProtocolMessageType('Setting', (_message.Message,), dict( 1218 | DESCRIPTOR = _SETTING, 1219 | __module__ = 'mcs_pb2' 1220 | # @@protoc_insertion_point(class_scope:Setting) 1221 | )) 1222 | _sym_db.RegisterMessage(Setting) 1223 | 1224 | HeartbeatStat = _reflection.GeneratedProtocolMessageType('HeartbeatStat', (_message.Message,), dict( 1225 | DESCRIPTOR = _HEARTBEATSTAT, 1226 | __module__ = 'mcs_pb2' 1227 | # @@protoc_insertion_point(class_scope:HeartbeatStat) 1228 | )) 1229 | _sym_db.RegisterMessage(HeartbeatStat) 1230 | 1231 | HeartbeatConfig = _reflection.GeneratedProtocolMessageType('HeartbeatConfig', (_message.Message,), dict( 1232 | DESCRIPTOR = _HEARTBEATCONFIG, 1233 | __module__ = 'mcs_pb2' 1234 | # @@protoc_insertion_point(class_scope:HeartbeatConfig) 1235 | )) 1236 | _sym_db.RegisterMessage(HeartbeatConfig) 1237 | 1238 | LoginRequest = _reflection.GeneratedProtocolMessageType('LoginRequest', (_message.Message,), dict( 1239 | DESCRIPTOR = _LOGINREQUEST, 1240 | __module__ = 'mcs_pb2' 1241 | # @@protoc_insertion_point(class_scope:LoginRequest) 1242 | )) 1243 | _sym_db.RegisterMessage(LoginRequest) 1244 | 1245 | LoginResponse = _reflection.GeneratedProtocolMessageType('LoginResponse', (_message.Message,), dict( 1246 | DESCRIPTOR = _LOGINRESPONSE, 1247 | __module__ = 'mcs_pb2' 1248 | # @@protoc_insertion_point(class_scope:LoginResponse) 1249 | )) 1250 | _sym_db.RegisterMessage(LoginResponse) 1251 | 1252 | StreamErrorStanza = _reflection.GeneratedProtocolMessageType('StreamErrorStanza', (_message.Message,), dict( 1253 | DESCRIPTOR = _STREAMERRORSTANZA, 1254 | __module__ = 'mcs_pb2' 1255 | # @@protoc_insertion_point(class_scope:StreamErrorStanza) 1256 | )) 1257 | _sym_db.RegisterMessage(StreamErrorStanza) 1258 | 1259 | Close = _reflection.GeneratedProtocolMessageType('Close', (_message.Message,), dict( 1260 | DESCRIPTOR = _CLOSE, 1261 | __module__ = 'mcs_pb2' 1262 | # @@protoc_insertion_point(class_scope:Close) 1263 | )) 1264 | _sym_db.RegisterMessage(Close) 1265 | 1266 | Extension = _reflection.GeneratedProtocolMessageType('Extension', (_message.Message,), dict( 1267 | DESCRIPTOR = _EXTENSION, 1268 | __module__ = 'mcs_pb2' 1269 | # @@protoc_insertion_point(class_scope:Extension) 1270 | )) 1271 | _sym_db.RegisterMessage(Extension) 1272 | 1273 | IqStanza = _reflection.GeneratedProtocolMessageType('IqStanza', (_message.Message,), dict( 1274 | DESCRIPTOR = _IQSTANZA, 1275 | __module__ = 'mcs_pb2' 1276 | # @@protoc_insertion_point(class_scope:IqStanza) 1277 | )) 1278 | _sym_db.RegisterMessage(IqStanza) 1279 | 1280 | AppData = _reflection.GeneratedProtocolMessageType('AppData', (_message.Message,), dict( 1281 | DESCRIPTOR = _APPDATA, 1282 | __module__ = 'mcs_pb2' 1283 | # @@protoc_insertion_point(class_scope:AppData) 1284 | )) 1285 | _sym_db.RegisterMessage(AppData) 1286 | 1287 | DataMessageStanza = _reflection.GeneratedProtocolMessageType('DataMessageStanza', (_message.Message,), dict( 1288 | DESCRIPTOR = _DATAMESSAGESTANZA, 1289 | __module__ = 'mcs_pb2' 1290 | # @@protoc_insertion_point(class_scope:DataMessageStanza) 1291 | )) 1292 | _sym_db.RegisterMessage(DataMessageStanza) 1293 | 1294 | StreamAck = _reflection.GeneratedProtocolMessageType('StreamAck', (_message.Message,), dict( 1295 | DESCRIPTOR = _STREAMACK, 1296 | __module__ = 'mcs_pb2' 1297 | # @@protoc_insertion_point(class_scope:StreamAck) 1298 | )) 1299 | _sym_db.RegisterMessage(StreamAck) 1300 | 1301 | SelectiveAck = _reflection.GeneratedProtocolMessageType('SelectiveAck', (_message.Message,), dict( 1302 | DESCRIPTOR = _SELECTIVEACK, 1303 | __module__ = 'mcs_pb2' 1304 | # @@protoc_insertion_point(class_scope:SelectiveAck) 1305 | )) 1306 | _sym_db.RegisterMessage(SelectiveAck) 1307 | 1308 | BindAccountRequest = _reflection.GeneratedProtocolMessageType('BindAccountRequest', (_message.Message,), dict( 1309 | DESCRIPTOR = _BINDACCOUNTREQUEST, 1310 | __module__ = 'mcs_pb2' 1311 | # @@protoc_insertion_point(class_scope:BindAccountRequest) 1312 | )) 1313 | _sym_db.RegisterMessage(BindAccountRequest) 1314 | 1315 | BindAccountResponse = _reflection.GeneratedProtocolMessageType('BindAccountResponse', (_message.Message,), dict( 1316 | DESCRIPTOR = _BINDACCOUNTRESPONSE, 1317 | __module__ = 'mcs_pb2' 1318 | # @@protoc_insertion_point(class_scope:BindAccountResponse) 1319 | )) 1320 | _sym_db.RegisterMessage(BindAccountResponse) 1321 | 1322 | 1323 | DESCRIPTOR.has_options = True 1324 | DESCRIPTOR._options = _descriptor._ParseOptions(descriptor_pb2.FileOptions(), _b('\n\026org.microg.gms.gcm.mcs')) 1325 | # @@protoc_insertion_point(module_scope) 1326 | --------------------------------------------------------------------------------