pax_global_header 0000666 0000000 0000000 00000000064 13221545743 0014520 g ustar 00root root 0000000 0000000 52 comment=c08f87d7e4db018ad4b3f81be1b68b18fefa0cc8
yowsup-2.5.7/ 0000775 0000000 0000000 00000000000 13221545743 0013101 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/.gitignore 0000664 0000000 0000000 00000000075 13221545743 0015073 0 ustar 00root root 0000000 0000000 *.pyc
*.class
todo
*.egg-info
tp
tests
dist
build
.idea
.tox
yowsup-2.5.7/.travis.yml 0000664 0000000 0000000 00000001267 13221545743 0015220 0 ustar 00root root 0000000 0000000 language: python
python: '3.5'
# command to install dependencies
env:
global:
- LD_PRELOAD=/lib/x86_64-linux-gnu/libSegFault.so
- SEGFAULT_SIGNALS=all
matrix:
- TOXENV=py26
- TOXENV=py27
- TOXENV=py33
- TOXENV=py34
- TOXENV=py35
before_install:
- python --version
- uname -a
- lsb_release -a
install:
- pip install tox
- virtualenv --version
- easy_install --version
- pip --version
- tox --version
# command to run tests
script:
- tox -v
after_failure:
- more .tox/log/* | cat
- more .tox/*/log/* | cat
before_cache:
- rm -rf $HOME/.cache/pip/log
cache:
directories:
- $HOME/.cache/pip
branches:
only:
- master
- develop
yowsup-2.5.7/LICENSE 0000664 0000000 0000000 00000104462 13221545743 0014115 0 ustar 00root root 0000000 0000000 GNU GENERAL PUBLIC LICENSE
Version 3, 29 June 2007
Copyright (C) 2007 Free Software Foundation, Inc.
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The GNU General Public License is a free, copyleft license for
software and other kinds of works.
The licenses for most software and other practical works are designed
to take away your freedom to share and change the works. By contrast,
the GNU General Public License is intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users. We, the Free Software Foundation, use the
GNU General Public License for most of our software; it applies also to
any other work released this way by its authors. You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.
To protect your rights, we need to prevent others from denying you
these rights or asking you to surrender the rights. Therefore, you have
certain responsibilities if you distribute copies of the software, or if
you modify it: responsibilities to respect the freedom of others.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must pass on to the recipients the same
freedoms that you received. You must make sure that they, too, receive
or can get the source code. And you must show them these terms so they
know their rights.
Developers that use the GNU GPL protect your rights with two steps:
(1) assert copyright on the software, and (2) offer you this License
giving you legal permission to copy, distribute and/or modify it.
For the developers' and authors' protection, the GPL clearly explains
that there is no warranty for this free software. For both users' and
authors' sake, the GPL requires that modified versions be marked as
changed, so that their problems will not be attributed erroneously to
authors of previous versions.
Some devices are designed to deny users access to install or run
modified versions of the software inside them, although the manufacturer
can do so. This is fundamentally incompatible with the aim of
protecting users' freedom to change the software. The systematic
pattern of such abuse occurs in the area of products for individuals to
use, which is precisely where it is most unacceptable. Therefore, we
have designed this version of the GPL to prohibit the practice for those
products. If such problems arise substantially in other domains, we
stand ready to extend this provision to those domains in future versions
of the GPL, as needed to protect the freedom of users.
Finally, every program is threatened constantly by software patents.
States should not allow patents to restrict development and use of
software on general-purpose computers, but in those that do, we wish to
avoid the special danger that patents applied to a free program could
make it effectively proprietary. To prevent this, the GPL assures that
patents cannot be used to render the program non-free.
The precise terms and conditions for copying, distribution and
modification follow.
TERMS AND CONDITIONS
0. Definitions.
"This License" refers to version 3 of the GNU General Public License.
"Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.
"The Program" refers to any copyrightable work licensed under this
License. Each licensee is addressed as "you". "Licensees" and
"recipients" may be individuals or organizations.
To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy. The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.
A "covered work" means either the unmodified Program or a work based
on the Program.
To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy. Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.
To "convey" a work means any kind of propagation that enables other
parties to make or receive copies. Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.
An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License. If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.
1. Source Code.
The "source code" for a work means the preferred form of the work
for making modifications to it. "Object code" means any non-source
form of a work.
A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.
The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form. A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.
The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities. However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work. For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.
The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.
The Corresponding Source for a work in source code form is that
same work.
2. Basic Permissions.
All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met. This License explicitly affirms your unlimited
permission to run the unmodified Program. The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work. This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.
You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force. You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright. Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.
Conveying under any other circumstances is permitted solely under
the conditions stated below. Sublicensing is not allowed; section 10
makes it unnecessary.
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.
When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.
4. Conveying Verbatim Copies.
You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.
You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.
5. Conveying Modified Source Versions.
You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:
a) The work must carry prominent notices stating that you modified
it, and giving a relevant date.
b) The work must carry prominent notices stating that it is
released under this License and any conditions added under section
7. This requirement modifies the requirement in section 4 to
"keep intact all notices".
c) You must license the entire work, as a whole, under this
License to anyone who comes into possession of a copy. This
License will therefore apply, along with any applicable section 7
additional terms, to the whole of the work, and all its parts,
regardless of how they are packaged. This License gives no
permission to license the work in any other way, but it does not
invalidate such permission if you have separately received it.
d) If the work has interactive user interfaces, each must display
Appropriate Legal Notices; however, if the Program has interactive
interfaces that do not display Appropriate Legal Notices, your
work need not make them do so.
A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit. Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.
6. Conveying Non-Source Forms.
You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:
a) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by the
Corresponding Source fixed on a durable physical medium
customarily used for software interchange.
b) Convey the object code in, or embodied in, a physical product
(including a physical distribution medium), accompanied by a
written offer, valid for at least three years and valid for as
long as you offer spare parts or customer support for that product
model, to give anyone who possesses the object code either (1) a
copy of the Corresponding Source for all the software in the
product that is covered by this License, on a durable physical
medium customarily used for software interchange, for a price no
more than your reasonable cost of physically performing this
conveying of source, or (2) access to copy the
Corresponding Source from a network server at no charge.
c) Convey individual copies of the object code with a copy of the
written offer to provide the Corresponding Source. This
alternative is allowed only occasionally and noncommercially, and
only if you received the object code with such an offer, in accord
with subsection 6b.
d) Convey the object code by offering access from a designated
place (gratis or for a charge), and offer equivalent access to the
Corresponding Source in the same way through the same place at no
further charge. You need not require recipients to copy the
Corresponding Source along with the object code. If the place to
copy the object code is a network server, the Corresponding Source
may be on a different server (operated by you or a third party)
that supports equivalent copying facilities, provided you maintain
clear directions next to the object code saying where to find the
Corresponding Source. Regardless of what server hosts the
Corresponding Source, you remain obligated to ensure that it is
available for as long as needed to satisfy these requirements.
e) Convey the object code using peer-to-peer transmission, provided
you inform other peers where the object code and Corresponding
Source of the work are being offered to the general public at no
charge under subsection 6d.
A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.
A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling. In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage. For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product. A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.
"Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source. The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.
If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information. But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).
The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed. Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.
Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.
7. Additional Terms.
"Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law. If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.
When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it. (Additional permissions may be written to require their own
removal in certain cases when you modify the work.) You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.
Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:
a) Disclaiming warranty or limiting liability differently from the
terms of sections 15 and 16 of this License; or
b) Requiring preservation of specified reasonable legal notices or
author attributions in that material or in the Appropriate Legal
Notices displayed by works containing it; or
c) Prohibiting misrepresentation of the origin of that material, or
requiring that modified versions of such material be marked in
reasonable ways as different from the original version; or
d) Limiting the use for publicity purposes of names of licensors or
authors of the material; or
e) Declining to grant rights under trademark law for use of some
trade names, trademarks, or service marks; or
f) Requiring indemnification of licensors and authors of that
material by anyone who conveys the material (or modified versions of
it) with contractual assumptions of liability to the recipient, for
any liability that these contractual assumptions directly impose on
those licensors and authors.
All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10. If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term. If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.
If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.
Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.
8. Termination.
You may not propagate or modify a covered work except as expressly
provided under this License. Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).
However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.
Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.
Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License. If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.
9. Acceptance Not Required for Having Copies.
You are not required to accept this License in order to receive or
run a copy of the Program. Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance. However,
nothing other than this License grants you permission to propagate or
modify any covered work. These actions infringe copyright if you do
not accept this License. Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.
10. Automatic Licensing of Downstream Recipients.
Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License. You are not responsible
for enforcing compliance by third parties with this License.
An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations. If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.
You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License. For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.
11. Patents.
A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based. The
work thus licensed is called the contributor's "contributor version".
A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version. For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.
Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.
In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement). To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.
If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients. "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.
If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.
A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License. You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.
Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.
12. No Surrender of Others' Freedom.
If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all. For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.
13. Use with the GNU Affero General Public License.
Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU Affero General Public License into a single
combined work, and to convey the resulting work. The terms of this
License will continue to apply to the part which is the covered work,
but the special requirements of the GNU Affero General Public License,
section 13, concerning interaction through a network will apply to the
combination as such.
14. Revised Versions of this License.
The Free Software Foundation may publish revised and/or new versions of
the GNU General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the
Program specifies that a certain numbered version of the GNU General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation. If the Program does not specify a version number of the
GNU General Public License, you may choose any version ever published
by the Free Software Foundation.
If the Program specifies that a proxy can decide which future
versions of the GNU General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.
Later license versions may give you additional or different
permissions. However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.
15. Disclaimer of Warranty.
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. Limitation of Liability.
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.
17. Interpretation of Sections 15 and 16.
If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
{one line to give the program's name and a brief idea of what it does.}
Copyright (C) {year} {name of author}
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see .
Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short
notice like this when it starts in an interactive mode:
{project} Copyright (C) {year} {fullname}
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, your program's commands
might be different; for a GUI interface, you would use an "about box".
You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU GPL, see
.
The GNU General Public License does not permit incorporating your program
into proprietary programs. If your program is a subroutine library, you
may consider it more useful to permit linking proprietary applications with
the library. If this is what you want to do, use the GNU Lesser General
Public License instead of this License. But first, please read
.
yowsup-2.5.7/MANIFEST.in 0000664 0000000 0000000 00000000041 13221545743 0014632 0 ustar 00root root 0000000 0000000 include yowsup/common/mime.types
yowsup-2.5.7/README.md 0000664 0000000 0000000 00000007766 13221545743 0014400 0 ustar 00root root 0000000 0000000 # Yowsup 2 [](https://travis-ci.org/tgalal/yowsup) [](https://gitter.im/tgalal/yowsup?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
## Updates (March 23, 2017)
Yowsup v2.5.7 is out, See [release notes](https://github.com/tgalal/yowsup/releases/tag/v2.5.7)
==========================================================
## Yowsup opened WhatsApp service under platforms!
Yowsup is a Python library that enables you to build applications which use the WhatsApp service. Yowsup has been used to create two clients: 1) An unofficial WhatsApp client Nokia N9 through the Wazapp project which was in use by more than 200K users; 2) Another fully featured unofficial client for Blackberry 10.
## Quickstart
* **[yowsup's architecture](https://github.com/tgalal/yowsup/wiki/Architecture)**
* **[Create a sample app](https://github.com/tgalal/yowsup/wiki/Sample-Application)**
* **[yowsup-cli](https://github.com/tgalal/yowsup/wiki/yowsup-cli-2.0)**
* **[Yowsup development, debugging, maintainance and sanity](https://github.com/tgalal/yowsup/wiki/Yowsup-development,-debugging,-maintainance-and-sanity)**
## Installation
- Requires python2.6+, or python3.0 +
- Required python packages: python-dateutil,
- Required python packages for end-to-end encryption: protobuf, pycrypto, python-axolotl-curve25519
- Required python packages for yowsup-cli: argparse, readline (or pyreadline for windows), pillow (for sending images)
Install using setup.py to pull all Python dependencies, or pip:
```
pip install yowsup2
```
### Linux
You need to have installed Python headers (probably from python-dev package) and ncurses-dev, then run
```
python setup.py install
```
Because of a bug with python-dateutil package you might get permission error for some dateutil file called requires.txt when you use yowsup (see [this bug report](https://bugs.launchpad.net/dateutil/+bug/1243202)) to fix you'll need to chmod 644 that file.
### FreeBSD (*BSD)
You need to have installed: py27-pip-7.1.2(+), py27-sqlite3-2.7.11_7(+), then run
```
pip install yowsup2
```
### Mac
```
python setup.py install
```
Administrators privileges might be required, if so then run with 'sudo'
### Windows
- Install [mingw](http://www.mingw.org/) compiler
- Add mingw to your PATH
- In PYTHONPATH\Lib\distutils create a file called distutils.cfg and add these lines:
```
[build]
compiler=mingw32
```
- Install gcc: ```mingw-get.exe install gcc```
- Install [zlib](http://www.zlib.net/)
- ```python setup.py install```
If pycrypto fails to install with some "chmod error". You can install it separately using something like
```easy_install http://www.voidspace.org.uk/downloads/pycrypto26/pycrypto-2.6.win32-py2.7.exe```
or for python3 from:
> [https://github.com/axper/python3-pycrypto-windows-installer](https://github.com/axper/python3-pycrypto-windows-installer)
and then rerun the install command again
# Special thanks
Special thanks to:
- [CODeRUS](https://github.com/CODeRUS)
- [mgp25](https://github.com/mgp25)
- [SikiFn](https://github.com/SikiFn)
- [0xTryCatch](https://github.com/0xTryCatch)
- [shirioko](https://github.com/shirioko)
and everyone else on the [WhatsAPI](https://github.com/mgp25/WhatsAPI-Official) project for their contributions to yowsup and the amazing effort they put into WhatsAPI, the PHP WhatsApp library
Special thanks goes to all other people who use and contribute to the library as well.
Please **[read this](https://github.com/tgalal/yowsup/wiki/Yowsup-development,-debugging,-maintainance-and-sanity)** if you'd like to contribute to yowsup 2.0
Thanks!
# License:
As of January 1, 2015 yowsup is licensed under the GPLv3+: http://www.gnu.org/licenses/gpl-3.0.html.
yowsup-2.5.7/setup.py 0000775 0000000 0000000 00000003001 13221545743 0014610 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
from __future__ import print_function
from setuptools import setup, find_packages
import yowsup
import platform
import sys
deps = ['python-dateutil', 'argparse', 'python-axolotl>=0.1.39', 'six==1.10']
if sys.version_info < (2,7):
deps += ['importlib', "protobuf==3.4.0"]
if platform.system().lower() == "windows":
deps.append('pyreadline')
else:
try:
import readline
except ImportError:
deps.append('readline')
setup(
name='yowsup2',
version=yowsup.__version__,
url='http://github.com/tgalal/yowsup/',
license='GPL-3+',
author='Tarek Galal',
tests_require=[],
install_requires = deps,
scripts = ['yowsup-cli'],
#cmdclass={'test': PyTest},
author_email='tare2.galal@gmail.com',
description='A WhatsApp python library',
#long_description=long_description,
packages= find_packages(),
include_package_data=True,
data_files = [('yowsup/common', ['yowsup/common/mime.types'])],
platforms='any',
#test_suite='',
classifiers = [
'Programming Language :: Python',
'Development Status :: 4 - Beta',
'Natural Language :: English',
#'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)',
'Operating System :: OS Independent',
'Topic :: Software Development :: Libraries :: Python Modules'
],
#extras_require={
# 'testing': ['pytest'],
#}
)
yowsup-2.5.7/tox.ini 0000664 0000000 0000000 00000000677 13221545743 0014426 0 ustar 00root root 0000000 0000000 # Tox (http://tox.testrun.org/) is a tool for running tests
# in multiple virtualenvs. This configuration file will run the
# test suite on all supported python versions. To use it, "pip install tox"
# and then run "tox" from this directory.
[tox]
skip_missing_interpreters = true
envlist = py26, py27, py32, py33, py34, py35, py36
[testenv]
commands = nosetests yowsup
deps =
py26: importlib
nose
python-dateutil
python-axolotl
yowsup-2.5.7/yowsup-cli 0000775 0000000 0000000 00000034337 13221545743 0015154 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
__version__ = "2.0.15"
__author__ = "Tarek Galal"
import sys, argparse, yowsup, logging
from yowsup.env import YowsupEnv
HELP_CONFIG = """
############# Yowsup Configuration Sample ###########
#
# ====================
# The file contains info about your WhatsApp account. This is used during registration and login.
# You can define or override all fields in the command line args as well.
#
# Country code. See http://www.ipipi.com/help/telephone-country-codes.htm. This is now required.
cc=49
#
# Your full phone number including the country code you defined in 'cc', without preceding '+' or '00'
phone=491234567890
#
# You obtain this password when you register using Yowsup.
password=NDkxNTIyNTI1NjAyMkBzLndoYXRzYXBwLm5ldA==
#######################################################
"""
CR_TEXT = """yowsup-cli v{cliVersion}
yowsup v{yowsupVersion}
Copyright (c) 2012-2016 Tarek Galal
http://www.openwhatsapp.org
This software is provided free of charge. Copying and redistribution is
encouraged.
If you appreciate this software and you would like to support future
development please consider donating:
http://openwhatsapp.org/yowsup/donate
"""
logger = logging.getLogger("yowsup-cli")
class YowArgParser(argparse.ArgumentParser):
def __init__(self, *args, **kwargs):
super(YowArgParser, self).__init__(*args, **kwargs)
self.add_argument("-v", "--version",
action = "store_true",
help = "Print version info and exit"
)
self.add_argument("-d", "--debug",
action = "store_true",
help = "Show debug messages"
)
self.add_argument("--help-config", help = "Prints a config file sample", action = "store_true")
self.args = {}
def getArgs(self):
return self.parse_args()
def getConfig(self, config):
try:
f = open(config)
out = {}
for l in f:
line = l.strip()
if len(line) and line[0] not in ('#',';'):
prep = line.split('#', 1)[0].split(';', 1)[0].split('=', 1)
varname = prep[0].strip()
val = prep[1].strip()
out[varname.replace('-', '_')] = val
return out
except IOError:
print("Invalid config path: %s" % config)
sys.exit(1)
def process(self):
self.args = vars(self.parse_args())
if self.args["debug"]:
logging.basicConfig(level = logging.DEBUG)
else:
logging.basicConfig(level = logging.INFO)
if self.args["version"]:
print("yowsup-cli v%s\nUsing yowsup v%s" % (__version__, yowsup.__version__))
sys.exit(0)
if self.args["help_config"]:
print(HELP_CONFIG)
sys.exit(0)
def printInfoText(self):
print(CR_TEXT.format(cliVersion=__version__, yowsupVersion=yowsup.__version__))
class RegistrationArgParser(YowArgParser):
def __init__(self, *args, **kwargs):
super(RegistrationArgParser, self).__init__(*args, **kwargs)
self.description = "WhatsApp Registration options"
configGroup = self.add_argument_group("Configuration options",
description = "Config file is optional. Other configuration arguments have higher priority if given, and will override those specified in the config file")
configGroup.add_argument("-c", '--config',
action = "store",
help = 'Path to config file. If this is not set then you must set at least --phone and --cc arguments')
configGroup.add_argument('-E', '--env',
action = "store",
help = "Set the environment yowsup simulates",
choices = YowsupEnv.getRegisteredEnvs())
configGroup.add_argument("-m", '--mcc',
action = "store",
help = "Mobile Country Code. Check your mcc here: https://en.wikipedia.org/wiki/Mobile_country_code")
configGroup.add_argument("-n", '--mnc',
action = "store",
help = "Mobile Network Code. Check your mnc from https://en.wikipedia.org/wiki/Mobile_country_code")
# configGroup.add_argument("-M", '--sim-mcc',
# action = "store",
# help = "Mobile Country Code. Check your mcc here: https://en.wikipedia.org/wiki/Mobile_country_code"
# )
# configGroup.add_argument("-N", '--sim-mnc',
# action= "store",
# help = "SIM MNC"
# )
configGroup.add_argument("-p", '--phone',
action= "store",
help = " Your full phone number including the country code you defined in 'cc', without preceeding '+' or '00'")
configGroup.add_argument("-C", '--cc',
action = "store",
help = "Country code. See http://www.ipipi.com/networkList.do. This is now required")
# configGroup.add_argument("-i", '--id',
# action="store",
# help = "Identity"
# )
regSteps = self.add_argument_group("Modes")
regSteps = regSteps.add_mutually_exclusive_group()
regSteps.add_argument("-r", '--requestcode', help='Request the digit registration code from Whatsapp.', action="store", required=False, metavar="(sms|voice)")
regSteps.add_argument("-R", '--register', help='Register account on Whatsapp using the code you previously received', action="store", required=False, metavar="code")
def process(self):
super(RegistrationArgParser, self).process()
config = self.getConfig(self.args["config"]) if self.args["config"] else {}
if self.args["env"]:
YowsupEnv.setEnv(self.args["env"])
if self.args["mcc"] : config["mcc"] = self.args["mcc"]
if self.args["mnc"] : config["mnc"] = self.args["mnc"]
if self.args["phone"] : config["phone"] = self.args["phone"]
if self.args["cc" ] : config["cc"] = self.args["cc"]
#if self.args["sim_mnc"] : config["sim_mnc"] = self.args["sim_mnc"]
#if self.args["sim_mcc"] : config["sim_mcc"] = self.args["sim_mcc"]
if not "mcc" in config: config["mcc"] = "000"
if not "mnc" in config: config["mnc"] = "000"
if not "sim_mcc" in config: config["sim_mcc"] = "000"
if not "sim_mnc" in config: config["sim_mnc"] = "000"
try:
assert self.args["requestcode"] or self.args["register"], "Must specify one of the modes -r/-R"
assert "cc" in config, "Must specify cc (country code)"
assert "phone" in config, "Must specify phone number"
except AssertionError as e:
print(e)
print("\n")
return False
if not config["phone"].startswith(config["cc"]):
print("Error, phone number does not start with the specified country code\n")
return False
config["phone"] = config["phone"][len(config["cc"]):]
if self.args["requestcode"]:
self.handleRequestCode(self.args["requestcode"], config)
elif self.args["register"]:
self.handleRegister(self.args["register"], config)
else:
return False
return True
def handleRequestCode(self, method, config):
from yowsup.registration import WACodeRequest
self.printInfoText()
codeReq = WACodeRequest(config["cc"],
config["phone"],
config["mcc"],
config["mnc"],
config["mcc"],
config["mnc"],
method
)
result = codeReq.send()
print(self.resultToString(result))
def handleRegister(self, code, config):
from yowsup.registration import WARegRequest
self.printInfoText()
code = code.replace('-', '')
req = WARegRequest(config["cc"], config["phone"], code)
result = req.send()
print(self.resultToString(result))
def resultToString(self, result):
unistr = str if sys.version_info >= (3, 0) else unicode
out = []
for k, v in result.items():
if v is None:
continue
out.append("%s: %s" %(k, v.encode("utf-8") if type(v) is unistr else v))
return "\n".join(out)
class DemosArgParser(YowArgParser):
def __init__(self, *args, **kwargs):
super(DemosArgParser, self).__init__(*args, **kwargs)
self.description = "Run a yowsup demo"
configGroup = self.add_argument_group("Configuration options for demos")
credentialsOpts = configGroup.add_mutually_exclusive_group()
credentialsOpts.add_argument("-l", "--login", action="store", metavar="phone:b64password",
help = "WhatsApp login credentials, in the format phonenumber:password, where password is base64 encoded.")
credentialsOpts.add_argument("-c", "--config", action="store",
help = "Path to config file containing authentication info. For more info about config format use --help-config")
configGroup.add_argument('-E', '--env',
action = "store",
help = "Set the environment yowsup simulates",
choices = YowsupEnv.getRegisteredEnvs())
configGroup.add_argument("-M", "--unmoxie", action="store_true", help="Disable E2E Encryption")
cmdopts = self.add_argument_group("Command line interface demo")
cmdopts.add_argument('-y', '--yowsup', action = "store_true", help = "Start the Yowsup command line client")
echoOpts = self.add_argument_group("Echo client demo")
echoOpts.add_argument('-e', '--echo', action = "store_true", help = "Start the Yowsup Echo client")
sendOpts = self.add_argument_group("Send client demo")
sendOpts.add_argument('-s', '--send', action="store", help = "Send a message to specified phone number, "
"wait for server receipt and exit",
metavar=("phone", "message"), nargs = 2)
syncContacts = self.add_argument_group("Sync contacts")
syncContacts.add_argument('-S','--sync', action = "store" , help = "Sync ( check valid ) whatsapp contacts",metavar =("contacts"))
def process(self):
super(DemosArgParser, self).process()
if self.args["env"]:
YowsupEnv.setEnv(self.args["env"])
if self.args["yowsup"]:
self.startCmdline()
elif self.args["echo"]:
self.startEcho()
elif self.args["send"]:
self.startSendClient()
elif self.args["sync"]:
self.startSyncContacts()
else:
return False
return True
def _getCredentials(self):
if self.args["login"]:
return tuple(self.args["login"].split(":"))
elif self.args["config"]:
config = self.getConfig(self.args["config"])
assert "password" in config and "phone" in config, "Must specify at least phone number and password in config file"
return config["phone"], config["password"]
else:
return None
def startCmdline(self):
from yowsup.demos import cli
credentials = self._getCredentials()
if not credentials:
print("Error: You must specify a configuration method")
sys.exit(1)
self.printInfoText()
stack = cli.YowsupCliStack(credentials, not self.args["unmoxie"])
stack.start()
def startEcho(self):
from yowsup.demos import echoclient
credentials = self._getCredentials()
if not credentials:
print("Error: You must specify a configuration method")
sys.exit(1)
try:
self.printInfoText()
stack = echoclient.YowsupEchoStack(credentials, not self.args["unmoxie"])
stack.start()
except KeyboardInterrupt:
print("\nYowsdown")
sys.exit(0)
def startSendClient(self):
from yowsup.demos import sendclient
credentials = self._getCredentials()
if not credentials:
print("Error: You must specify a configuration method")
sys.exit(1)
try:
self.printInfoText()
stack = sendclient.YowsupSendStack(credentials, [([self.args["send"][0], self.args["send"][1]])],
not self.args["unmoxie"])
stack.start()
except KeyboardInterrupt:
print("\nYowsdown")
sys.exit(0)
def startSyncContacts(self):
from yowsup.demos import contacts
credentials = self._getCredentials()
if not credentials:
print("Error: You must specify a configuration method")
sys.exit(1)
try:
self.printInfoText()
stack = contacts.YowsupSyncStack(credentials,self.args["sync"].split(','), not self.args["unmoxie"])
stack.start()
except KeyboardInterrupt:
print("\nYowsdown")
sys.exit(0)
if __name__ == "__main__":
args = sys.argv
if(len(args) > 1):
del args[0]
modeDict = {
"demos": DemosArgParser,
"registration": RegistrationArgParser,
"version": None
}
if(len(args) == 0 or args[0] not in modeDict):
print("Available commands:\n===================")
print(", ".join(modeDict.keys()))
sys.exit(1)
mode = args[0]
if mode == "version":
print("yowsup-cli v%s\nUsing yowsup v%s" % (__version__, yowsup.__version__))
sys.exit(0)
else:
parser = modeDict[mode]()
if not parser.process():
parser.print_help()
yowsup-2.5.7/yowsup/ 0000775 0000000 0000000 00000000000 13221545743 0014447 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/__init__.py 0000664 0000000 0000000 00000000061 13221545743 0016555 0 ustar 00root root 0000000 0000000 __version__ = "2.5.7"
__author__ = "Tarek Galal"
yowsup-2.5.7/yowsup/common/ 0000775 0000000 0000000 00000000000 13221545743 0015737 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/common/__init__.py 0000664 0000000 0000000 00000000043 13221545743 0020045 0 ustar 00root root 0000000 0000000 from .constants import YowConstants yowsup-2.5.7/yowsup/common/constants.py 0000664 0000000 0000000 00000001432 13221545743 0020325 0 ustar 00root root 0000000 0000000 class YowConstants:
DOMAIN = "s.whatsapp.net"
ENDPOINTS = (
("e1.whatsapp.net", 443),
("e2.whatsapp.net", 443),
("e3.whatsapp.net", 443),
("e4.whatsapp.net", 443),
("e5.whatsapp.net", 443),
("e6.whatsapp.net", 443),
("e7.whatsapp.net", 443),
("e8.whatsapp.net", 443),
("e9.whatsapp.net", 443),
("e10.whatsapp.net", 443),
("e11.whatsapp.net", 443),
("e12.whatsapp.net", 443),
("e13.whatsapp.net", 443),
("e14.whatsapp.net", 443),
("e15.whatsapp.net", 443),
("e16.whatsapp.net", 443),
)
WHATSAPP_SERVER = "s.whatsapp.net"
WHATSAPP_GROUP_SERVER = "g.us"
PATH_STORAGE = "~/.yowsup"
PREVIEW_WIDTH = 64
PREVIEW_HEIGHT = 64
yowsup-2.5.7/yowsup/common/http/ 0000775 0000000 0000000 00000000000 13221545743 0016716 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/common/http/__init__.py 0000664 0000000 0000000 00000000162 13221545743 0021026 0 ustar 00root root 0000000 0000000 from .httpproxy import HttpProxy
from .warequest import WARequest
from .waresponseparser import JSONResponseParser yowsup-2.5.7/yowsup/common/http/httpproxy.py 0000664 0000000 0000000 00000006323 13221545743 0021355 0 ustar 00root root 0000000 0000000 '''
Copyright (c) <2012> Tarek Galal
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''
import os, base64
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
class HttpProxy:
def __init__(self, address, username = None, password = None):
self.address = address
self.username = username
self.password = password
def __repr__(self):
return repr(self.address)
def handler(self):
return HttpProxyHandler(self)
@staticmethod
def getFromEnviron():
url = None
for key in ('http_proxy', 'https_proxy'):
url = os.environ.get(key)
if url: break
if not url:
return None
dat = urlparse(url)
port = 80 if dat.scheme == 'http' else 443
if dat.port != None: port = int(dat.port)
host = dat.hostname
return HttpProxy((host, port), dat.username, dat.password)
class HttpProxyHandler:
def __init__(self, proxy):
self.state = 'init'
self.proxy = proxy
def onConnect(self):
pass
def connect(self, socket, pair):
proxy = self.proxy
authHeader = None
if proxy.username and proxy.password:
key = bytes(proxy.username, 'ascii') + b':' + bytes(proxy.password, 'ascii') if (bytes != str) else bytes(proxy.username) + b':' + proxy.password
auth = base64.b64encode(key)
authHeader = b'Proxy-Authorization: Basic ' + auth + b'\r\n'
data = bytearray('CONNECT %s:%d HTTP/1.1\r\nHost: %s:%d\r\n' % (2 * pair), 'ascii')
if authHeader:
data += authHeader
data += b'\r\n'
self.state = 'connect'
self.data = data
socket.connect(proxy.address)
def send(self, socket):
if self.state == 'connect':
socket.send(self.data)
self.state = 'sent'
def recv(self, socket, size):
if self.state == 'sent':
data = socket.recv(size)
data = data.decode('ascii')
status = data.split(' ', 2)
if status[1] != '200':
raise Exception('%s' % (data[:data.index('\r\n')]))
self.state = 'end'
self.onConnect()
return data yowsup-2.5.7/yowsup/common/http/test_warequest.py 0000664 0000000 0000000 00000000062 13221545743 0022345 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest yowsup-2.5.7/yowsup/common/http/warequest.py 0000664 0000000 0000000 00000010756 13221545743 0021321 0 ustar 00root root 0000000 0000000 import urllib,sys, os, logging
import hashlib
from .waresponseparser import ResponseParser
from yowsup.env import YowsupEnv
if sys.version_info < (3, 0):
import httplib
from urllib import urlencode
if sys.version_info >= (2, 7, 9):
#see https://github.com/tgalal/yowsup/issues/677
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
else:
from http import client as httplib
from urllib.parse import urlencode
logger = logging.getLogger(__name__)
class WARequest(object):
OK = 200
def __init__(self):
self.pvars = []
self.port = 443
self.type = "GET"
self.parser = None
self.params = []
self.headers = {}
self.sent = False
self.response = None
def setParsableVariables(self, pvars):
self.pvars = pvars
def onResponse(self, name, value):
if name == "status":
self.status = value
elif name == "result":
self.result = value
def addParam(self,name,value):
self.params.append((name,value))
def removeParam(self, name):
for i in range(0, len(self.params)):
if self.params[i][0] == name:
del self.params[i]
def addHeaderField(self, name, value):
self.headers[name] = value
def clearParams(self):
self.params = []
def getUserAgent(self):
return YowsupEnv.getCurrent().getUserAgent()
def send(self, parser = None):
if self.type == "POST":
return self.sendPostRequest(parser)
return self.sendGetRequest(parser)
def setParser(self, parser):
if isinstance(parser, ResponseParser):
self.parser = parser
else:
logger.error("Invalid parser")
def getConnectionParameters(self):
if not self.url:
return "", "", self.port
try:
url = self.url.split("://", 1)
url = url[0] if len(url) == 1 else url[1]
host, path = url.split('/', 1)
except ValueError:
host = url
path = ""
path = "/" + path
return host, self.port, path
def sendGetRequest(self, parser = None):
self.response = None
params = self.params#[param.items()[0] for param in self.params];
parser = parser or self.parser or ResponseParser()
headers = dict(list({"User-Agent":self.getUserAgent(),
"Accept": parser.getMeta()
}.items()) + list(self.headers.items()));
host,port,path = self.getConnectionParameters()
self.response = WARequest.sendRequest(host, port, path, headers, params, "GET")
if not self.response.status == WARequest.OK:
logger.error("Request not success, status was %s"%self.response.status)
return {}
data = self.response.read()
logger.info(data)
self.sent = True
return parser.parse(data.decode(), self.pvars)
def sendPostRequest(self, parser = None):
self.response = None
params = self.params #[param.items()[0] for param in self.params];
parser = parser or self.parser or ResponseParser()
headers = dict(list({"User-Agent":self.getUserAgent(),
"Accept": parser.getMeta(),
"Content-Type":"application/x-www-form-urlencoded"
}.items()) + list(self.headers.items()))
host,port,path = self.getConnectionParameters()
self.response = WARequest.sendRequest(host, port, path, headers, params, "POST")
if not self.response.status == WARequest.OK:
logger.error("Request not success, status was %s" % self.response.status)
return {}
data = self.response.read()
logger.info(data)
self.sent = True
return parser.parse(data.decode(), self.pvars)
@staticmethod
def sendRequest(host, port, path, headers, params, reqType="GET"):
params = urlencode(params)
path = path + "?"+ params if reqType == "GET" and params else path
if len(headers):
logger.debug(headers)
if len(params):
logger.debug(params)
logger.debug("Opening connection to %s" % host);
conn = httplib.HTTPSConnection(host ,port) if port == 443 else httplib.HTTPConnection(host ,port)
logger.debug("Sending %s request to %s" % (reqType, path))
conn.request(reqType, path, params, headers);
response = conn.getresponse()
return response
yowsup-2.5.7/yowsup/common/http/waresponseparser.py 0000664 0000000 0000000 00000010320 13221545743 0022667 0 ustar 00root root 0000000 0000000 import json, sys
from xml.dom import minidom
import plistlib
import logging
logger = logging.getLogger(__name__)
class ResponseParser(object):
def __init__(self):
self.meta = "*"
def parse(self, text, pvars):
return text
def getMeta(self):
return self.meta
def getVars(self, pvars):
if type(pvars) is dict:
return pvars
if type(pvars) is list:
out = {}
for p in pvars:
out[p] = p
return out
class XMLResponseParser(ResponseParser):
def __init__(self):
try:
import libxml2
except ImportError:
print("libxml2 XMLResponseParser requires libxml2")
sys.exit(1)
self.meta = "text/xml";
def parse(self, xml, pvars):
import libxml2
doc = libxml2.parseDoc(xml)
pvars = self.getVars(pvars)
vals = {}
for k, v in pvars.items():
res = doc.xpathEval(v)
vals[k] = []
for r in res:
#if not vals.has_key(r.name):
# vals[r.name] = []
if r.type == 'element':
#vals[r.name].append(self.xmlToDict(minidom.parseString(str(r)))[r.name])
vals[k].append(self.xmlToDict(minidom.parseString(str(r)))[r.name])
elif r.type == 'attribute':
vals[k].append(r.content)
else:
logger.error("UNKNOWN TYPE")
if len(vals[k]) == 1:
vals[k] = vals[k][0]
elif len(vals[k]) == 0:
vals[k] = None
return vals
def xmlToDict(self, xmlNode):
if xmlNode.nodeName == "#document":
node = {xmlNode.firstChild.nodeName:{}}
node[xmlNode.firstChild.nodeName] = self.xmlToDict(xmlNode.firstChild)
return node
node = {}
curr = node
if xmlNode.attributes:
for name, value in xmlNode.attributes.items():
curr[name] = value
for n in xmlNode.childNodes:
if n.nodeType == n.TEXT_NODE:
curr["__TEXT__"] = n.data
continue
if not n.nodeName in curr:
curr[n.nodeName] = []
if len(xmlNode.getElementsByTagName(n.nodeName)) > 1:
#curr[n.nodeName] = []
curr[n.nodeName].append(self.xmlToDict(n))
else:
curr[n.nodeName] = self.xmlToDict(n)
return node
class JSONResponseParser(ResponseParser):
def __init__(self):
self.meta = "text/json"
def parse(self, jsonData, pvars):
d = json.loads(jsonData)
pvars = self.getVars(pvars)
parsed = {}
for k,v in pvars.items():
parsed[k] = self.query(d, v)
return parsed
def query(self, d, key):
keys = key.split('.', 1)
currKey = keys[0]
if(currKey in d):
item = d[currKey]
if len(keys) == 1:
return item
if type(item) is dict:
return self.query(item, keys[1])
elif type(item) is list:
output = []
for i in item:
output.append(self.query(i, keys[1]))
return output
else:
return None
class PListResponseParser(ResponseParser):
def __init__(self):
self.meta = "text/xml"
def parse(self, xml, pvars):
#tmp = minidom.parseString(xml)
if sys.version_info >= (3, 0):
pl = plistlib.readPlistFromBytes(xml.encode());
else:
pl = plistlib.readPlistFromString(xml);
parsed= {}
pvars = self.getVars(pvars)
for k,v in pvars.items():
parsed[k] = pl[k] if k in pl else None
return parsed;
yowsup-2.5.7/yowsup/common/mime.types 0000664 0000000 0000000 00000000665 13221545743 0017763 0 ustar 00root root 0000000 0000000 audio/3gpp 3gpp
audio/aac aac
audio/aiff aif
audio/amr amr
audio/mp4 m4a
audio/mpeg mp3 mp2 mpga mpega
audio/ogg oga ogg opus spx
audio/qcelp qcp
audio/wav wav
audio/webm webm
audio/x-caf caf
audio/x-ms-wma wma
audio/ogg ogg
image/gif gif
image/jpeg jpe jpg jpeg
image/png png
video/3gpp 3gp
video/avi avi
video/mp4 mp4
video/mpeg m1v mpeg mpa mpg mpe
video/quicktime mov qt
video/x-flv flv
video/x-ms-asf asf asx
yowsup-2.5.7/yowsup/common/optionalmodules.py 0000664 0000000 0000000 00000003313 13221545743 0021527 0 ustar 00root root 0000000 0000000 import importlib
import logging
logger = logging.getLogger(__name__)
from contextlib import contextmanager
class OptionalModule(object):
def __init__(self, modulename, failMessage = None, require = False):
self.modulename = modulename
self.require = require
self.failMessage = failMessage
def __enter__(self):
return self.importFn
def importFn(self, what = None):
imp = self.modulename if not what else ("%s.%s" % (self.modulename, what))
return importlib.import_module(imp)
def __exit__(self, exc_type, exc_val, exc_tb):
if isinstance(exc_val, ImportError):
failMessage = self.failMessage if self.failMessage is not None else ("%s import failed" % self.modulename)
if failMessage:
logger.error(failMessage)
if self.require:
raise
return True
class PILOptionalModule(OptionalModule):
def __init__(self, failMessage = None, require = False):
super(PILOptionalModule, self).__init__("PIL",
failMessage= failMessage,
require = require)
class FFVideoOptionalModule(OptionalModule):
def __init__(self, failMessage = None, require = False):
super(FFVideoOptionalModule, self).__init__("ffvideo",
failMessage=failMessage,
require=require)
class AxolotlOptionalModule(OptionalModule):
def __init__(self, failMessage = None, require = False):
super(AxolotlOptionalModule, self).__init__("axolotl",
failMessage=failMessage,
require=require)
if __name__ == "__main__":
with PILOptionalModule() as imp:
imp()
print("OK")
print("DONE")
yowsup-2.5.7/yowsup/common/tools.py 0000664 0000000 0000000 00000013117 13221545743 0017454 0 ustar 00root root 0000000 0000000 import time,datetime,re, hashlib
import calendar
from dateutil import tz
import os
from .constants import YowConstants
import codecs, sys
import logging
import tempfile
import base64
import hashlib
import os.path, mimetypes
from .optionalmodules import PILOptionalModule, FFVideoOptionalModule
logger = logging.getLogger(__name__)
class Jid:
@staticmethod
def normalize(number):
if '@' in number:
return number
elif "-" in number:
return "%s@%s" % (number, YowConstants.WHATSAPP_GROUP_SERVER)
return "%s@%s" % (number, YowConstants.WHATSAPP_SERVER)
class HexTools:
decode_hex = codecs.getdecoder("hex_codec")
@staticmethod
def decodeHex(hexString):
result = HexTools.decode_hex(hexString)[0]
if sys.version_info >= (3,0):
result = result.decode('latin-1')
return result
class WATools:
@staticmethod
def generateIdentity():
return os.urandom(20)
@staticmethod
def getFileHashForUpload(filePath):
sha1 = hashlib.sha256()
f = open(filePath, 'rb')
try:
sha1.update(f.read())
finally:
f.close()
b64Hash = base64.b64encode(sha1.digest())
return b64Hash if type(b64Hash) is str else b64Hash.decode()
class StorageTools:
@staticmethod
def constructPath(*path):
path = os.path.join(*path)
fullPath = os.path.expanduser(os.path.join(YowConstants.PATH_STORAGE, path))
if not os.path.exists(os.path.dirname(fullPath)):
os.makedirs(os.path.dirname(fullPath))
return fullPath
@staticmethod
def getStorageForPhone(phone):
return StorageTools.constructPath(phone + '/')
@staticmethod
def writeIdentity(phone, identity):
path = StorageTools.getStorageForPhone(phone)
with open(os.path.join(path, "id"), 'wb') as idFile:
idFile.write(identity)
@staticmethod
def getIdentity(phone):
path = StorageTools.getStorageForPhone(phone)
out = None
idPath = os.path.join(path, "id")
if os.path.isfile(idPath):
with open(idPath, 'rb') as idFile:
out = idFile.read()
return out
@staticmethod
def writeNonce(phone, nonce):
path = StorageTools.getStorageForPhone(phone)
with open(os.path.join(path, "nonce"), 'wb') as idFile:
idFile.write(nonce.encode("latin-1") if sys.version_info >= (3,0) else nonce)
@staticmethod
def getNonce(phone):
path = StorageTools.getStorageForPhone(phone)
out = None
noncePath = os.path.join(path, "nonce")
if os.path.isfile(noncePath):
with open(noncePath, 'rb') as idFile:
out = idFile.read()
return out
class TimeTools:
@staticmethod
def parseIso(iso):
d=datetime.datetime(*map(int, re.split('[^\d]', iso)[:-1]))
return d
@staticmethod
def utcToLocal(dt):
utc = tz.gettz('UTC')
local = tz.tzlocal()
dtUtc = dt.replace(tzinfo=utc)
return dtUtc.astimezone(local)
@staticmethod
def utcTimestamp():
utcNow = datetime.datetime.utcnow()
return calendar.timegm(utcNow.timetuple())
@staticmethod
def datetimeToTimestamp(dt):
return time.mktime(dt.timetuple())
class ImageTools:
@staticmethod
def scaleImage(infile, outfile, imageFormat, width, height):
with PILOptionalModule() as imp:
Image = imp("Image")
im = Image.open(infile)
#Convert P mode images
if im.mode != "RGB":
im = im.convert("RGB")
im.thumbnail((width, height))
im.save(outfile, imageFormat)
return True
return False
@staticmethod
def getImageDimensions(imageFile):
with PILOptionalModule() as imp:
Image = imp("Image")
im = Image.open(imageFile)
return im.size
@staticmethod
def generatePreviewFromImage(image):
fd, path = tempfile.mkstemp()
preview = None
if ImageTools.scaleImage(image, path, "JPEG", YowConstants.PREVIEW_WIDTH, YowConstants.PREVIEW_HEIGHT):
fileObj = os.fdopen(fd, "rb+")
fileObj.seek(0)
preview = fileObj.read()
fileObj.close()
os.remove(path)
return preview
class MimeTools:
MIME_FILE = os.path.join(os.path.dirname(__file__), 'mime.types')
mimetypes.init() # Load default mime.types
try:
mimetypes.init([MIME_FILE]) # Append whatsapp mime.types
except exception as e:
logger.warning("Mime types supported can't be read. System mimes will be used. Cause: " + e.message)
@staticmethod
def getMIME(filepath):
mimeType = mimetypes.guess_type(filepath)[0]
if mimeType is None:
raise Exception("Unsupported/unrecognized file type for: "+filepath);
return mimeType
class VideoTools:
@staticmethod
def getVideoProperties(videoFile):
with FFVideoOptionalModule() as imp:
VideoStream = imp("VideoStream")
s = VideoStream(videoFile)
return s.width, s.height, s.bitrate, s.duration #, s.codec_name
@staticmethod
def generatePreviewFromVideo(videoFile):
with FFVideoOptionalModule() as imp:
VideoStream = imp("VideoStream")
fd, path = tempfile.mkstemp('.jpg')
stream = VideoStream(videoFile)
stream.get_frame_at_sec(0).image().save(path)
preview = ImageTools.generatePreviewFromImage(path)
os.remove(path)
return preview
yowsup-2.5.7/yowsup/demos/ 0000775 0000000 0000000 00000000000 13221545743 0015556 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/__init__.py 0000664 0000000 0000000 00000000000 13221545743 0017655 0 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/cli/ 0000775 0000000 0000000 00000000000 13221545743 0016325 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/cli/__init__.py 0000664 0000000 0000000 00000000042 13221545743 0020432 0 ustar 00root root 0000000 0000000 from .stack import YowsupCliStack
yowsup-2.5.7/yowsup/demos/cli/cli.py 0000664 0000000 0000000 00000013607 13221545743 0017455 0 ustar 00root root 0000000 0000000 import threading, inspect, shlex
try:
import Queue
except ImportError:
import queue as Queue
try:
import readline
except ImportError:
import pyreadline as readline
class clicmd(object):
def __init__(self, desc, order = 0):
self.desc = desc
self.order = order
def __call__(self, fn):
fn.clidesc = self.desc
fn.cliorder = self.order
return fn
class Cli(object):
def __init__(self):
self.sentCache = {}
self.commands = {}
self.acceptingInput = False
self.lastPrompt = True
self.blockingQueue = Queue.Queue()
self._queuedCmds = []
readline.set_completer(self.complete)
readline.parse_and_bind('tab: complete')
members = inspect.getmembers(self, predicate = inspect.ismethod)
for m in members:
if hasattr(m[1], "clidesc"):
fname = m[0]
fn = m[1]
try:
cmd, subcommand = fname.split('_')
except ValueError:
cmd = fname
subcommand = "_"
if not cmd in self.commands:
self.commands[cmd] = {}
self.commands[cmd][subcommand] = {
"args": inspect.getargspec(fn)[0][1:],
"optional": len(inspect.getargspec(fn)[3]) if inspect.getargspec(fn)[3] else 0,
"desc": fn.clidesc,
"fn": fn,
"order": fn.cliorder
}
#self.cv = threading.Condition()
self.inputThread = threading.Thread(target = self.startInputThread)
self.inputThread.daemon = True
def queueCmd(self, cmd):
self._queuedCmds.append(cmd)
def startInput(self):
self.inputThread.start()
################### cmd input parsing ####################
def print_usage(self):
line_width = 100
outArr = []
def addToOut(ind, cmd):
if ind >= len(outArr):
outArr.extend([None] * (ind - len(outArr) + 1))
if outArr[ind] != None:
for i in range(len(outArr) - 1, 0, -1):
if outArr[i] is None:
outArr[i] = outArr[ind]
outArr[ind] = cmd
return
outArr.append(cmd)
else:
outArr[ind] = cmd
for cmd, subcommands in self.commands.items():
for subcmd, subcmdDetails in subcommands.items():
out = ""
out += ("/%s " % cmd).ljust(15)
out += ("%s " % subcmd if subcmd != "_" else "").ljust(15)
args = ("%s " % " ".join(["<%s>" % c for c in subcmdDetails["args"][0:len(subcmdDetails["args"])-subcmdDetails["optional"]]]))
args += ("%s " % " ".join(["[%s]" % c for c in subcmdDetails["args"][len(subcmdDetails["args"])-subcmdDetails["optional"]:]]))
out += args.ljust(30)
out += subcmdDetails["desc"].ljust(20)
addToOut(subcmdDetails["order"], out)
print("----------------------------------------------")
print("\n" . join(outArr))
print("----------------------------------------------")
def execCmd(self, cmdInput):
cmdInput = cmdInput.rstrip()
if not len(cmdInput) > 1:
return
if cmdInput.startswith("/"):
cmdInput = cmdInput[1:]
else:
self.print_usage()
return
cmdInputDissect = [c for c in shlex.split(cmdInput) if c]
cmd = cmdInputDissect[0]
if not cmd in self.commands:
return self.print_usage()
cmdData = self.commands[cmd]
if len(cmdData) == 1 and "_" in cmdData:
subcmdData = cmdData["_"]
args = cmdInputDissect[1:] if len(cmdInputDissect) > 1 else []
else:
args = cmdInputDissect[2:] if len(cmdInputDissect) > 2 else []
subcmd = cmdInputDissect[1] if len(cmdInputDissect) > 1 else ""
if subcmd not in cmdData:
return self.print_usage()
subcmdData = cmdData[subcmd]
targetFn = subcmdData["fn"]
if len(subcmdData["args"]) < len(args) or len(subcmdData["args"]) - subcmdData["optional"] > len(args):
return self.print_usage()
return self.doExecCmd(lambda :targetFn(*args))
def doExecCmd(self, fn):
return fn()
def startInputThread(self):
#cv.acquire()
# Fix Python 2.x.
global input
try: input = raw_input
except NameError: pass
while(True):
cmd = self._queuedCmds.pop(0) if len(self._queuedCmds) else input(self.getPrompt()).strip()
wait = self.execCmd(cmd)
if wait:
self.acceptingInput = False
self.blockingQueue.get(True)
#cv.wait()
#self.inputThread.wait()
self.acceptingInput = True
#cv.release()
def getPrompt(self):
return "[%s]:" % ("connected" if self.connected else "offline")
def printPrompt(self):
#return "Enter Message or command: (/%s)" % ", /".join(self.commandMappings)
print(self.getPrompt())
def output(self, message, tag = "general", prompt = True):
if self.acceptingInput == True and self.lastPrompt is True:
print("")
self.lastPrompt = prompt
if tag is not None:
print("%s: %s" % (tag, message))
else:
print(message)
if prompt:
self.printPrompt()
def complete(self, text, state):
if state == 0:
for cmd in self.commands:
if cmd.startswith(text) and cmd != text:
return cmd
def notifyInputThread(self):
self.blockingQueue.put(1)
if __name__ == "__main__":
c = Cli()
c.print_usage()
yowsup-2.5.7/yowsup/demos/cli/layer.py 0000664 0000000 0000000 00000061124 13221545743 0020017 0 ustar 00root root 0000000 0000000 from .cli import Cli, clicmd
from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers import YowLayerEvent, EventCallback
from yowsup.layers.network import YowNetworkLayer
import sys
from yowsup.common import YowConstants
import datetime
import os
import logging
from yowsup.layers.protocol_groups.protocolentities import *
from yowsup.layers.protocol_presence.protocolentities import *
from yowsup.layers.protocol_messages.protocolentities import *
from yowsup.layers.protocol_ib.protocolentities import *
from yowsup.layers.protocol_iq.protocolentities import *
from yowsup.layers.protocol_contacts.protocolentities import *
from yowsup.layers.protocol_chatstate.protocolentities import *
from yowsup.layers.protocol_privacy.protocolentities import *
from yowsup.layers.protocol_media.protocolentities import *
from yowsup.layers.protocol_media.mediauploader import MediaUploader
from yowsup.layers.protocol_profiles.protocolentities import *
from yowsup.common.tools import Jid
from yowsup.common.optionalmodules import PILOptionalModule, AxolotlOptionalModule
logger = logging.getLogger(__name__)
class YowsupCliLayer(Cli, YowInterfaceLayer):
PROP_RECEIPT_AUTO = "org.openwhatsapp.yowsup.prop.cli.autoreceipt"
PROP_RECEIPT_KEEPALIVE = "org.openwhatsapp.yowsup.prop.cli.keepalive"
PROP_CONTACT_JID = "org.openwhatsapp.yowsup.prop.cli.contact.jid"
EVENT_LOGIN = "org.openwhatsapp.yowsup.event.cli.login"
EVENT_START = "org.openwhatsapp.yowsup.event.cli.start"
EVENT_SENDANDEXIT = "org.openwhatsapp.yowsup.event.cli.sendandexit"
MESSAGE_FORMAT = "[{FROM}({TIME})]:[{MESSAGE_ID}]\t {MESSAGE}"
FAIL_OPT_PILLOW = "No PIL library installed, try install pillow"
FAIL_OPT_AXOLOTL = "axolotl is not installed, try install python-axolotl"
DISCONNECT_ACTION_PROMPT = 0
DISCONNECT_ACTION_EXIT = 1
ACCOUNT_DEL_WARNINGS = 4
def __init__(self):
super(YowsupCliLayer, self).__init__()
YowInterfaceLayer.__init__(self)
self.accountDelWarnings = 0
self.connected = False
self.username = None
self.sendReceipts = True
self.sendRead = True
self.disconnectAction = self.__class__.DISCONNECT_ACTION_PROMPT
self.credentials = None
#add aliases to make it user to use commands. for example you can then do:
# /message send foobar "HI"
# and then it will get automaticlaly mapped to foobar's jid
self.jidAliases = {
# "NAME": "PHONE@s.whatsapp.net"
}
def aliasToJid(self, calias):
for alias, ajid in self.jidAliases.items():
if calias.lower() == alias.lower():
return Jid.normalize(ajid)
return Jid.normalize(calias)
def jidToAlias(self, jid):
for alias, ajid in self.jidAliases.items():
if ajid == jid:
return alias
return jid
def setCredentials(self, username, password):
self.getLayerInterface(YowAuthenticationProtocolLayer).setCredentials(username, password)
return "%s@s.whatsapp.net" % username
@EventCallback(EVENT_START)
def onStart(self, layerEvent):
self.startInput()
return True
@EventCallback(EVENT_SENDANDEXIT)
def onSendAndExit(self, layerEvent):
credentials = layerEvent.getArg("credentials")
target = layerEvent.getArg("target")
message = layerEvent.getArg("message")
self.sendMessageAndDisconnect(credentials, target, message)
return True
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
def onStateDisconnected(self,layerEvent):
self.output("Disconnected: %s" % layerEvent.getArg("reason"))
if self.disconnectAction == self.__class__.DISCONNECT_ACTION_PROMPT:
self.connected = False
self.notifyInputThread()
else:
os._exit(os.EX_OK)
def assertConnected(self):
if self.connected:
return True
else:
self.output("Not connected", tag = "Error", prompt = False)
return False
#### batch cmds #####
def sendMessageAndDisconnect(self, credentials, jid, message):
self.disconnectAction = self.__class__.DISCONNECT_ACTION_EXIT
self.queueCmd("/login %s %s" % credentials)
self.queueCmd("/message send %s \"%s\" wait" % (jid, message))
self.queueCmd("/disconnect")
self.startInput()
########## PRESENCE ###############
@clicmd("Set presence name")
def presence_name(self, name):
if self.assertConnected():
entity = PresenceProtocolEntity(name = name)
self.toLower(entity)
@clicmd("Set presence as available")
def presence_available(self):
if self.assertConnected():
entity = AvailablePresenceProtocolEntity()
self.toLower(entity)
@clicmd("Set presence as unavailable")
def presence_unavailable(self):
if self.assertConnected():
entity = UnavailablePresenceProtocolEntity()
self.toLower(entity)
@clicmd("Unsubscribe from contact's presence updates")
def presence_unsubscribe(self, contact):
if self.assertConnected():
entity = UnsubscribePresenceProtocolEntity(self.aliasToJid(contact))
self.toLower(entity)
@clicmd("Subscribe to contact's presence updates")
def presence_subscribe(self, contact):
if self.assertConnected():
entity = SubscribePresenceProtocolEntity(self.aliasToJid(contact))
self.toLower(entity)
########### END PRESENCE #############
########### ib #######################
@clicmd("Send clean dirty")
def ib_clean(self, dirtyType):
if self.assertConnected():
entity = CleanIqProtocolEntity("groups", YowConstants.DOMAIN)
self.toLower(entity)
@clicmd("Ping server")
def ping(self):
if self.assertConnected():
entity = PingIqProtocolEntity(to = YowConstants.DOMAIN)
self.toLower(entity)
######################################
####### contacts/ profiles ####################
@clicmd("Set status text")
def profile_setStatus(self, text):
if self.assertConnected():
def onSuccess(resultIqEntity, originalIqEntity):
self.output("Status updated successfully")
def onError(errorIqEntity, originalIqEntity):
logger.error("Error updating status")
entity = SetStatusIqProtocolEntity(text)
self._sendIq(entity, onSuccess, onError)
@clicmd("Get profile picture for contact")
def contact_picture(self, jid):
if self.assertConnected():
entity = GetPictureIqProtocolEntity(self.aliasToJid(jid), preview=False)
self._sendIq(entity, self.onGetContactPictureResult)
@clicmd("Get profile picture preview for contact")
def contact_picturePreview(self, jid):
if self.assertConnected():
entity = GetPictureIqProtocolEntity(self.aliasToJid(jid), preview=True)
self._sendIq(entity, self.onGetContactPictureResult)
@clicmd("Get lastseen for contact")
def contact_lastseen(self, jid):
if self.assertConnected():
def onSuccess(resultIqEntity, originalIqEntity):
self.output("%s lastseen %s seconds ago" % (resultIqEntity.getFrom(), resultIqEntity.getSeconds()))
def onError(errorIqEntity, originalIqEntity):
logger.error("Error getting lastseen information for %s" % originalIqEntity.getTo())
entity = LastseenIqProtocolEntity(self.aliasToJid(jid))
self._sendIq(entity, onSuccess, onError)
@clicmd("Set profile picture")
def profile_setPicture(self, path):
if self.assertConnected():
with PILOptionalModule(failMessage = "No PIL library installed, try install pillow") as imp:
Image = imp("Image")
def onSuccess(resultIqEntity, originalIqEntity):
self.output("Profile picture updated successfully")
def onError(errorIqEntity, originalIqEntity):
logger.error("Error updating profile picture")
#example by @aesedepece in https://github.com/tgalal/yowsup/pull/781
#modified to support python3
src = Image.open(path)
pictureData = src.resize((640, 640)).tobytes("jpeg", "RGB")
picturePreview = src.resize((96, 96)).tobytes("jpeg", "RGB")
iq = SetPictureIqProtocolEntity(self.getOwnJid(), picturePreview, pictureData)
self._sendIq(iq, onSuccess, onError)
@clicmd("Get profile privacy")
def profile_getPrivacy(self):
if self.assertConnected():
def onSuccess(resultIqEntity, originalIqEntity):
self.output("Profile privacy is: %s" %(resultIqEntity))
def onError(errorIqEntity, originalIqEntity):
logger.error("Error getting profile privacy")
iq = GetPrivacyIqProtocolEntity()
self._sendIq(iq, onSuccess, onError)
@clicmd("Profile privacy. value=all|contacts|none names=profile|status|last. Names are comma separated, defaults to all.")
def profile_setPrivacy(self, value="all", names=None):
if self.assertConnected():
def onSuccess(resultIqEntity, originalIqEntity):
self.output("Profile privacy set to: %s" %(resultIqEntity))
def onError(errorIqEntity, originalIqEntity):
logger.error("Error setting profile privacy")
try:
names = [name for name in names.split(',')] if names else None
iq = SetPrivacyIqProtocolEntity(value, names)
self._sendIq(iq, onSuccess, onError)
except Exception as inst:
self.output(inst.message)
return self.print_usage()
########### groups
@clicmd("List all groups you belong to", 5)
def groups_list(self):
if self.assertConnected():
entity = ListGroupsIqProtocolEntity()
self.toLower(entity)
@clicmd("Leave a group you belong to", 4)
def group_leave(self, group_jid):
if self.assertConnected():
entity = LeaveGroupsIqProtocolEntity([self.aliasToJid(group_jid)])
self.toLower(entity)
@clicmd("Create a new group with the specified subject and participants. Jids are a comma separated list but optional.", 3)
def groups_create(self, subject, jids = None):
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')] if jids else []
entity = CreateGroupsIqProtocolEntity(subject, participants=jids)
self.toLower(entity)
@clicmd("Invite to group. Jids are a comma separated list")
def group_invite(self, group_jid, jids):
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')]
entity = AddParticipantsIqProtocolEntity(self.aliasToJid(group_jid), jids)
self.toLower(entity)
@clicmd("Promote admin of a group. Jids are a comma separated list")
def group_promote(self, group_jid, jids):
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')]
entity = PromoteParticipantsIqProtocolEntity(self.aliasToJid(group_jid), jids)
self.toLower(entity)
@clicmd("Remove admin of a group. Jids are a comma separated list")
def group_demote(self, group_jid, jids):
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')]
entity = DemoteParticipantsIqProtocolEntity(self.aliasToJid(group_jid), jids)
self.toLower(entity)
@clicmd("Kick from group. Jids are a comma separated list")
def group_kick(self, group_jid, jids):
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')]
entity = RemoveParticipantsIqProtocolEntity(self.aliasToJid(group_jid), jids)
self.toLower(entity)
@clicmd("Change group subject")
def group_setSubject(self, group_jid, subject):
if self.assertConnected():
entity = SubjectGroupsIqProtocolEntity(self.aliasToJid(group_jid), subject)
self.toLower(entity)
@clicmd("Set group picture")
def group_picture(self, group_jid, path):
if self.assertConnected():
with PILOptionalModule(failMessage = self.__class__.FAIL_OPT_PILLOW) as imp:
Image = imp("Image")
def onSuccess(resultIqEntity, originalIqEntity):
self.output("Group picture updated successfully")
def onError(errorIqEntity, originalIqEntity):
logger.error("Error updating Group picture")
#example by @aesedepece in https://github.com/tgalal/yowsup/pull/781
#modified to support python3
src = Image.open(path)
pictureData = src.resize((640, 640)).tobytes("jpeg", "RGB")
picturePreview = src.resize((96, 96)).tobytes("jpeg", "RGB")
iq = SetPictureIqProtocolEntity(self.aliasToJid(group_jid), picturePreview, pictureData)
self._sendIq(iq, onSuccess, onError)
@clicmd("Get group info")
def group_info(self, group_jid):
if self.assertConnected():
entity = InfoGroupsIqProtocolEntity(self.aliasToJid(group_jid))
self.toLower(entity)
@clicmd("Get shared keys")
def keys_get(self, jids):
with AxolotlOptionalModule(failMessage = self.__class__.FAIL_OPT_AXOLOTL) as importFn:
importFn()
from yowsup.layers.axolotl.protocolentities.iq_key_get import GetKeysIqProtocolEntity
if self.assertConnected():
jids = [self.aliasToJid(jid) for jid in jids.split(',')]
entity = GetKeysIqProtocolEntity(jids)
self.toLower(entity)
@clicmd("Send init seq")
def seq(self):
priv = PrivacyListIqProtocolEntity()
self.toLower(priv)
push = PushIqProtocolEntity()
self.toLower(push)
props = PropsIqProtocolEntity()
self.toLower(props)
crypto = CryptoIqProtocolEntity()
self.toLower(crypto)
@clicmd("Delete your account")
def account_delete(self):
if self.assertConnected():
if self.accountDelWarnings < self.__class__.ACCOUNT_DEL_WARNINGS:
self.accountDelWarnings += 1
remaining = self.__class__.ACCOUNT_DEL_WARNINGS - self.accountDelWarnings
self.output("Repeat delete command another %s times to send the delete request" % remaining, tag="Account delete Warning !!", prompt = False)
else:
entity = UnregisterIqProtocolEntity()
self.toLower(entity)
@clicmd("Send message to a friend")
def message_send(self, number, content):
if self.assertConnected():
outgoingMessage = TextMessageProtocolEntity(content.encode("utf-8") if sys.version_info >= (3,0) else content, to = self.aliasToJid(number))
self.toLower(outgoingMessage)
@clicmd("Broadcast message. numbers should comma separated phone numbers")
def message_broadcast(self, numbers, content):
if self.assertConnected():
jids = [self.aliasToJid(number) for number in numbers.split(',')]
outgoingMessage = BroadcastTextMessage(jids, content)
self.toLower(outgoingMessage)
#@clicmd("Send read receipt")
def message_read(self, message_id):
pass
#@clicmd("Send delivered receipt")
def message_delivered(self, message_id):
pass
@clicmd("Send a video with optional caption")
def video_send(self, number, path, caption = None):
self.media_send(number, path, RequestUploadIqProtocolEntity.MEDIA_TYPE_VIDEO)
@clicmd("Send an image with optional caption")
def image_send(self, number, path, caption = None):
self.media_send(number, path, RequestUploadIqProtocolEntity.MEDIA_TYPE_IMAGE)
@clicmd("Send audio file")
def audio_send(self, number, path):
self.media_send(number, path, RequestUploadIqProtocolEntity.MEDIA_TYPE_AUDIO)
def media_send(self, number, path, mediaType, caption = None):
if self.assertConnected():
jid = self.aliasToJid(number)
entity = RequestUploadIqProtocolEntity(mediaType, filePath=path)
successFn = lambda successEntity, originalEntity: self.onRequestUploadResult(jid, mediaType, path, successEntity, originalEntity, caption)
errorFn = lambda errorEntity, originalEntity: self.onRequestUploadError(jid, path, errorEntity, originalEntity)
self._sendIq(entity, successFn, errorFn)
self._sendIq(entity, successFn, errorFn)
@clicmd("Send typing state")
def state_typing(self, jid):
if self.assertConnected():
entity = OutgoingChatstateProtocolEntity(ChatstateProtocolEntity.STATE_TYPING, self.aliasToJid(jid))
self.toLower(entity)
@clicmd("Request contacts statuses")
def statuses_get(self, contacts):
if self.assertConnected():
entity = GetStatusesIqProtocolEntity([self.aliasToJid(c) for c in contacts.split(',')])
self.toLower(entity)
@clicmd("Send paused state")
def state_paused(self, jid):
if self.assertConnected():
entity = OutgoingChatstateProtocolEntity(ChatstateProtocolEntity.STATE_PAUSED, self.aliasToJid(jid))
self.toLower(entity)
@clicmd("Sync contacts, contacts should be comma separated phone numbers, with no spaces")
def contacts_sync(self, contacts):
if self.assertConnected():
entity = GetSyncIqProtocolEntity(contacts.split(','))
self.toLower(entity)
@clicmd("Disconnect")
def disconnect(self):
if self.assertConnected():
self.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT))
@clicmd("Quick login")
def L(self):
if self.connected:
return self.output("Already connected, disconnect first")
self.getLayerInterface(YowNetworkLayer).connect()
return True
@clicmd("Login to WhatsApp", 0)
def login(self, username, b64password):
self.setCredentials(username, b64password)
return self.L()
######## receive #########
@ProtocolEntityCallback("chatstate")
def onChatstate(self, entity):
print(entity)
@ProtocolEntityCallback("iq")
def onIq(self, entity):
print(entity)
@ProtocolEntityCallback("receipt")
def onReceipt(self, entity):
self.toLower(entity.ack())
@ProtocolEntityCallback("ack")
def onAck(self, entity):
#formattedDate = datetime.datetime.fromtimestamp(self.sentCache[entity.getId()][0]).strftime('%d-%m-%Y %H:%M')
#print("%s [%s]:%s"%(self.username, formattedDate, self.sentCache[entity.getId()][1]))
if entity.getClass() == "message":
self.output(entity.getId(), tag = "Sent")
#self.notifyInputThread()
@ProtocolEntityCallback("success")
def onSuccess(self, entity):
self.connected = True
self.output("Logged in!", "Auth", prompt = False)
self.notifyInputThread()
@ProtocolEntityCallback("failure")
def onFailure(self, entity):
self.connected = False
self.output("Login Failed, reason: %s" % entity.getReason(), prompt = False)
@ProtocolEntityCallback("notification")
def onNotification(self, notification):
notificationData = notification.__str__()
if notificationData:
self.output(notificationData, tag = "Notification")
else:
self.output("From :%s, Type: %s" % (self.jidToAlias(notification.getFrom()), notification.getType()), tag = "Notification")
if self.sendReceipts:
self.toLower(notification.ack())
@ProtocolEntityCallback("message")
def onMessage(self, message):
messageOut = ""
if message.getType() == "text":
#self.output(message.getBody(), tag = "%s [%s]"%(message.getFrom(), formattedDate))
messageOut = self.getTextMessageBody(message)
elif message.getType() == "media":
messageOut = self.getMediaMessageBody(message)
else:
messageOut = "Unknown message type %s " % message.getType()
print(messageOut.toProtocolTreeNode())
formattedDate = datetime.datetime.fromtimestamp(message.getTimestamp()).strftime('%d-%m-%Y %H:%M')
sender = message.getFrom() if not message.isGroupMessage() else "%s/%s" % (message.getParticipant(False), message.getFrom())
output = self.__class__.MESSAGE_FORMAT.format(
FROM = sender,
TIME = formattedDate,
MESSAGE = messageOut.encode('latin-1').decode() if sys.version_info >= (3, 0) else messageOut,
MESSAGE_ID = message.getId()
)
self.output(output, tag = None, prompt = not self.sendReceipts)
if self.sendReceipts:
self.toLower(message.ack(self.sendRead))
self.output("Sent delivered receipt"+" and Read" if self.sendRead else "", tag = "Message %s" % message.getId())
def getTextMessageBody(self, message):
return message.getBody()
def getMediaMessageBody(self, message):
if message.getMediaType() in ("image", "audio", "video"):
return self.getDownloadableMediaMessageBody(message)
else:
return "[Media Type: %s]" % message.getMediaType()
def getDownloadableMediaMessageBody(self, message):
return "[Media Type:{media_type}, Size:{media_size}, URL:{media_url}]".format(
media_type = message.getMediaType(),
media_size = message.getMediaSize(),
media_url = message.getMediaUrl()
)
def doSendMedia(self, mediaType, filePath, url, to, ip = None, caption = None):
if mediaType == RequestUploadIqProtocolEntity.MEDIA_TYPE_IMAGE:
entity = ImageDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to, caption = caption)
elif mediaType == RequestUploadIqProtocolEntity.MEDIA_TYPE_AUDIO:
entity = AudioDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to)
elif mediaType == RequestUploadIqProtocolEntity.MEDIA_TYPE_VIDEO:
entity = VideoDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to, caption = caption)
self.toLower(entity)
def __str__(self):
return "CLI Interface Layer"
########### callbacks ############
def onRequestUploadResult(self, jid, mediaType, filePath, resultRequestUploadIqProtocolEntity, requestUploadIqProtocolEntity, caption = None):
if resultRequestUploadIqProtocolEntity.isDuplicate():
self.doSendMedia(mediaType, filePath, resultRequestUploadIqProtocolEntity.getUrl(), jid,
resultRequestUploadIqProtocolEntity.getIp(), caption)
else:
successFn = lambda filePath, jid, url: self.doSendMedia(mediaType, filePath, url, jid, resultRequestUploadIqProtocolEntity.getIp(), caption)
mediaUploader = MediaUploader(jid, self.getOwnJid(), filePath,
resultRequestUploadIqProtocolEntity.getUrl(),
resultRequestUploadIqProtocolEntity.getResumeOffset(),
successFn, self.onUploadError, self.onUploadProgress, async=False)
mediaUploader.start()
def onRequestUploadError(self, jid, path, errorRequestUploadIqProtocolEntity, requestUploadIqProtocolEntity):
logger.error("Request upload for file %s for %s failed" % (path, jid))
def onUploadError(self, filePath, jid, url):
logger.error("Upload file %s to %s for %s failed!" % (filePath, url, jid))
def onUploadProgress(self, filePath, jid, url, progress):
sys.stdout.write("%s => %s, %d%% \r" % (os.path.basename(filePath), jid, progress))
sys.stdout.flush()
def onGetContactPictureResult(self, resultGetPictureIqProtocolEntiy, getPictureIqProtocolEntity):
# do here whatever you want
# write to a file
# or open
# or do nothing
# write to file example:
#resultGetPictureIqProtocolEntiy.writeToFile("/tmp/yowpics/%s_%s.jpg" % (getPictureIqProtocolEntity.getTo(), "preview" if resultGetPictureIqProtocolEntiy.isPreview() else "full"))
pass
def __str__(self):
return "CLI Interface Layer"
@clicmd("Print this message")
def help(self):
self.print_usage()
yowsup-2.5.7/yowsup/demos/cli/stack.py 0000664 0000000 0000000 00000002112 13221545743 0020000 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStackBuilder
from .layer import YowsupCliLayer
from yowsup.layers.auth import AuthError
from yowsup.layers import YowLayerEvent
from yowsup.layers.axolotl.props import PROP_IDENTITY_AUTOTRUST
import sys
class YowsupCliStack(object):
def __init__(self, credentials, encryptionEnabled = True):
stackBuilder = YowStackBuilder()
self.stack = stackBuilder\
.pushDefaultLayers(encryptionEnabled)\
.push(YowsupCliLayer)\
.build()
# self.stack.setCredentials(credentials)
self.stack.setCredentials(credentials)
self.stack.setProp(PROP_IDENTITY_AUTOTRUST, True)
def start(self):
print("Yowsup Cli client\n==================\nType /help for available commands\n")
self.stack.broadcastEvent(YowLayerEvent(YowsupCliLayer.EVENT_START))
try:
self.stack.loop(timeout = 0.5, discrete = 0.5)
except AuthError as e:
print("Auth Error, reason %s" % e)
except KeyboardInterrupt:
print("\nYowsdown")
sys.exit(0)
yowsup-2.5.7/yowsup/demos/contacts/ 0000775 0000000 0000000 00000000000 13221545743 0017374 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/contacts/__init__.py 0000664 0000000 0000000 00000000043 13221545743 0021502 0 ustar 00root root 0000000 0000000 from .stack import YowsupSyncStack
yowsup-2.5.7/yowsup/demos/contacts/layer.py 0000664 0000000 0000000 00000002316 13221545743 0021064 0 ustar 00root root 0000000 0000000 from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_contacts.protocolentities import GetSyncIqProtocolEntity, ResultSyncIqProtocolEntity
from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity
import threading
import logging
logger = logging.getLogger(__name__)
class SyncLayer(YowInterfaceLayer):
PROP_CONTACTS = "org.openwhatsapp.yowsup.prop.syncdemo.contacts"
def __init__(self):
super(SyncLayer, self).__init__()
#call back function when there is a successful connection to whatsapp server
@ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
contacts= self.getProp(self.__class__.PROP_CONTACTS, [])
contactEntity = GetSyncIqProtocolEntity(contacts)
self._sendIq(contactEntity, self.onGetSyncResult, self.onGetSyncError)
def onGetSyncResult(self, resultSyncIqProtocolEntity, originalIqProtocolEntity):
print(resultSyncIqProtocolEntity)
raise KeyboardInterrupt()
def onGetSyncError(self, errorSyncIqProtocolEntity, originalIqProtocolEntity):
print(errorSyncIqProtocolEntity)
raise KeyboardInterrupt()
yowsup-2.5.7/yowsup/demos/contacts/stack.py 0000664 0000000 0000000 00000002145 13221545743 0021055 0 ustar 00root root 0000000 0000000 from .layer import SyncLayer
from yowsup.stacks import YowStackBuilder
from yowsup.layers.auth import AuthError
from yowsup.layers import YowLayerEvent
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers.network import YowNetworkLayer
class YowsupSyncStack(object):
def __init__(self, credentials, contacts, encryptionEnabled = False):
"""
:param credentials:
:param contacts: list of [jid ]
:param encryptionEnabled:
:return:
"""
stackBuilder = YowStackBuilder()
self.stack = stackBuilder \
.pushDefaultLayers(encryptionEnabled) \
.push(SyncLayer) \
.build()
self.stack.setProp(SyncLayer.PROP_CONTACTS, contacts)
self.stack.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True)
self.stack.setCredentials(credentials)
def start(self):
self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
try:
self.stack.loop()
except AuthError as e:
print("Authentication Error: %s" % e.message)
yowsup-2.5.7/yowsup/demos/echoclient/ 0000775 0000000 0000000 00000000000 13221545743 0017673 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/echoclient/__init__.py 0000664 0000000 0000000 00000000042 13221545743 0022000 0 ustar 00root root 0000000 0000000 from .stack import YowsupEchoStack yowsup-2.5.7/yowsup/demos/echoclient/layer.py 0000664 0000000 0000000 00000003156 13221545743 0021366 0 ustar 00root root 0000000 0000000 from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
class EchoLayer(YowInterfaceLayer):
@ProtocolEntityCallback("message")
def onMessage(self, messageProtocolEntity):
if messageProtocolEntity.getType() == 'text':
self.onTextMessage(messageProtocolEntity)
elif messageProtocolEntity.getType() == 'media':
self.onMediaMessage(messageProtocolEntity)
self.toLower(messageProtocolEntity.forward(messageProtocolEntity.getFrom()))
self.toLower(messageProtocolEntity.ack())
self.toLower(messageProtocolEntity.ack(True))
@ProtocolEntityCallback("receipt")
def onReceipt(self, entity):
self.toLower(entity.ack())
def onTextMessage(self,messageProtocolEntity):
# just print info
print("Echoing %s to %s" % (messageProtocolEntity.getBody(), messageProtocolEntity.getFrom(False)))
def onMediaMessage(self, messageProtocolEntity):
# just print info
if messageProtocolEntity.getMediaType() == "image":
print("Echoing image %s to %s" % (messageProtocolEntity.url, messageProtocolEntity.getFrom(False)))
elif messageProtocolEntity.getMediaType() == "location":
print("Echoing location (%s, %s) to %s" % (messageProtocolEntity.getLatitude(), messageProtocolEntity.getLongitude(), messageProtocolEntity.getFrom(False)))
elif messageProtocolEntity.getMediaType() == "vcard":
print("Echoing vcard (%s, %s) to %s" % (messageProtocolEntity.getName(), messageProtocolEntity.getCardData(), messageProtocolEntity.getFrom(False)))
yowsup-2.5.7/yowsup/demos/echoclient/stack.py 0000664 0000000 0000000 00000001375 13221545743 0021360 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStackBuilder
from .layer import EchoLayer
from yowsup.layers.auth import AuthError
from yowsup.layers import YowLayerEvent
from yowsup.layers.network import YowNetworkLayer
class YowsupEchoStack(object):
def __init__(self, credentials, encryptionEnabled = True):
stackBuilder = YowStackBuilder()
self.stack = stackBuilder\
.pushDefaultLayers(encryptionEnabled)\
.push(EchoLayer)\
.build()
self.stack.setCredentials(credentials)
def start(self):
self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
try:
self.stack.loop()
except AuthError as e:
print("Authentication Error: %s" % e.message)
yowsup-2.5.7/yowsup/demos/sendclient/ 0000775 0000000 0000000 00000000000 13221545743 0017706 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/demos/sendclient/__init__.py 0000664 0000000 0000000 00000000042 13221545743 0022013 0 ustar 00root root 0000000 0000000 from .stack import YowsupSendStack yowsup-2.5.7/yowsup/demos/sendclient/layer.py 0000664 0000000 0000000 00000003741 13221545743 0021401 0 ustar 00root root 0000000 0000000 from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
from yowsup.common.tools import Jid
import threading
import logging
logger = logging.getLogger(__name__)
class SendLayer(YowInterfaceLayer):
#This message is going to be replaced by the @param message in YowsupSendStack construction
#i.e. list of (jid, message) tuples
PROP_MESSAGES = "org.openwhatsapp.yowsup.prop.sendclient.queue"
def __init__(self):
super(SendLayer, self).__init__()
self.ackQueue = []
self.lock = threading.Condition()
#call back function when there is a successful connection to whatsapp server
@ProtocolEntityCallback("success")
def onSuccess(self, successProtocolEntity):
self.lock.acquire()
for target in self.getProp(self.__class__.PROP_MESSAGES, []):
#getProp() is trying to retreive the list of (jid, message) tuples, if none exist, use the default []
phone, message = target
messageEntity = TextMessageProtocolEntity(message, to = Jid.normalize(phone))
#append the id of message to ackQueue list
#which the id of message will be deleted when ack is received.
self.ackQueue.append(messageEntity.getId())
self.toLower(messageEntity)
self.lock.release()
#after receiving the message from the target number, target number will send a ack to sender(us)
@ProtocolEntityCallback("ack")
def onAck(self, entity):
self.lock.acquire()
#if the id match the id in ackQueue, then pop the id of the message out
if entity.getId() in self.ackQueue:
self.ackQueue.pop(self.ackQueue.index(entity.getId()))
if not len(self.ackQueue):
self.lock.release()
logger.info("Message sent")
raise KeyboardInterrupt()
self.lock.release()
yowsup-2.5.7/yowsup/demos/sendclient/stack.py 0000664 0000000 0000000 00000002160 13221545743 0021364 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStackBuilder
from .layer import SendLayer
from yowsup.layers.auth import AuthError
from yowsup.layers import YowLayerEvent
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers.network import YowNetworkLayer
class YowsupSendStack(object):
def __init__(self, credentials, messages, encryptionEnabled = True):
"""
:param credentials:
:param messages: list of (jid, message) tuples
:param encryptionEnabled:
:return:
"""
stackBuilder = YowStackBuilder()
self.stack = stackBuilder\
.pushDefaultLayers(encryptionEnabled)\
.push(SendLayer)\
.build()
self.stack.setProp(SendLayer.PROP_MESSAGES, messages)
self.stack.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True)
self.stack.setCredentials(credentials)
def start(self):
self.stack.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECT))
try:
self.stack.loop()
except AuthError as e:
print("Authentication Error: %s" % e.message)
yowsup-2.5.7/yowsup/env/ 0000775 0000000 0000000 00000000000 13221545743 0015237 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/env/__init__.py 0000664 0000000 0000000 00000000147 13221545743 0017352 0 ustar 00root root 0000000 0000000 from .env import YowsupEnv
from .env_android import AndroidYowsupEnv
from .env_s40 import S40YowsupEnv
yowsup-2.5.7/yowsup/env/env.py 0000664 0000000 0000000 00000005020 13221545743 0016376 0 ustar 00root root 0000000 0000000 import abc
import logging
from six import with_metaclass
logger = logging.getLogger(__name__)
DEFAULT = "s40"
class YowsupEnvType(abc.ABCMeta):
def __init__(cls, name, bases, dct):
if name != "YowsupEnv":
YowsupEnv.registerEnv(cls)
super(YowsupEnvType, cls).__init__(name, bases, dct)
class YowsupEnv(with_metaclass(YowsupEnvType, object)):
__metaclass__ = YowsupEnvType
__ENVS = {}
__CURR = None
_USERAGENT_STRING = "WhatsApp/{WHATSAPP_VERSION} {OS_NAME}/{OS_VERSION} Device/{MANUFACTURER}-{DEVICE_NAME}"
@classmethod
def registerEnv(cls, envCls):
envName = envCls.__name__.lower().replace("yowsupenv", "")
cls.__ENVS[envName] = envCls
logger.debug("registered env %s => %s" % (envName, envCls))
@classmethod
def setEnv(cls, envName):
if not envName in cls.__ENVS:
raise ValueError("%s env does not exist" % envName)
logger.debug("Current env changed to %s " % envName)
cls.__CURR = cls.__ENVS[envName]()
@classmethod
def getEnv(cls, envName):
if not envName in cls.__ENVS:
raise ValueError("%s env does not exist" % envName)
return cls.__ENVS[envName]()
@classmethod
def getRegisteredEnvs(cls):
return list(cls.__ENVS.keys())
@classmethod
def getCurrent(cls):
if cls.__CURR is None:
env = DEFAULT
envs = cls.getRegisteredEnvs()
if env not in envs:
env = envs[0]
logger.debug("Env not set, setting it to %s" % env)
cls.setEnv(env)
return cls.__CURR
@abc.abstractmethod
def getToken(self, phoneNumber):
pass
@abc.abstractmethod
def getVersion(self):
pass
@abc.abstractmethod
def getOSVersion(self):
pass
@abc.abstractmethod
def getOSName(self):
pass
@abc.abstractmethod
def getDeviceName(self):
pass
@abc.abstractmethod
def getManufacturer(self):
pass
@abc.abstractmethod
def isAxolotlEnabled(self):
pass
def getBuildVersion(self):
return ""
def getResource(self):
return self.getOSName() + "-" + self.getVersion()
def getUserAgent(self):
return self.__class__._USERAGENT_STRING.format(
WHATSAPP_VERSION = self.getVersion(),
OS_NAME = self.getOSName(),
OS_VERSION = self.getOSVersion(),
MANUFACTURER = self.getManufacturer(),
DEVICE_NAME = self.getDeviceName()
)
yowsup-2.5.7/yowsup/env/env_android.py 0000664 0000000 0000000 00000005751 13221545743 0020111 0 ustar 00root root 0000000 0000000 from .env import YowsupEnv
import base64
import hashlib
class AndroidYowsupEnv(YowsupEnv):
_SIGNATURE = "MIIDMjCCAvCgAwIBAgIETCU2pDALBgcqhkjOOAQDBQAwfDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNV" \
"BAcTC1NhbnRhIENsYXJhMRYwFAYDVQQKEw1XaGF0c0FwcCBJbmMuMRQwEgYDVQQLEwtFbmdpbmVlcmluZzEUMBIGA1UEAxMLQnJ" \
"pYW4gQWN0b24wHhcNMTAwNjI1MjMwNzE2WhcNNDQwMjE1MjMwNzE2WjB8MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5" \
"pYTEUMBIGA1UEBxMLU2FudGEgQ2xhcmExFjAUBgNVBAoTDVdoYXRzQXBwIEluYy4xFDASBgNVBAsTC0VuZ2luZWVyaW5nMRQwEg" \
"YDVQQDEwtCcmlhbiBBY3RvbjCCAbgwggEsBgcqhkjOOAQBMIIBHwKBgQD9f1OBHXUSKVLfSpwu7OTn9hG3UjzvRADDHj+AtlEm" \
"aUVdQCJR+1k9jVj6v8X1ujD2y5tVbNeBO4AdNG/yZmC3a5lQpaSfn+gEexAiwk+7qdf+t8Yb+DtX58aophUPBPuD9tPFHsMCN" \
"VQTWhaRMvZ1864rYdcq7/IiAxmd0UgBxwIVAJdgUI8VIwvMspK5gqLrhAvwWBz1AoGBAPfhoIXWmz3ey7yrXDa4V7l5lK+7+jr" \
"qgvlXTAs9B4JnUVlXjrrUWU/mcQcQgYC0SRZxI+hMKBYTt88JMozIpuE8FnqLVHyNKOCjrh4rs6Z1kW6jfwv6ITVi8ftiegEkO" \
"8yk8b6oUZCJqIPf4VrlnwaSi2ZegHtVJWQBTDv+z0kqA4GFAAKBgQDRGYtLgWh7zyRtQainJfCpiaUbzjJuhMgo4fVWZIvXHaS" \
"HBU1t5w//S0lDK2hiqkj8KpMWGywVov9eZxZy37V26dEqr/c2m5qZ0E+ynSu7sqUD7kGx/zeIcGT0H+KAVgkGNQCo5Uc0koLRW" \
"YHNtYoIvt5R3X6YZylbPftF/8ayWTALBgcqhkjOOAQDBQADLwAwLAIUAKYCp0d6z4QQdyN74JDfQ2WCyi8CFDUM4CaNB+ceVXd" \
"KtOrNTQcc0e+t"
_MD5_CLASSES = "uts7K11+PDyZE5R0ou+2Sw=="
_KEY = "eQV5aq/Cg63Gsq1sshN9T3gh+UUp0wIw0xgHYT1bnCjEqOJQKCRrWxdAe2yvsDeCJL+Y4G3PRD2HUF7oUgiGo8vGlNJOaux26k+A2F3hj8A="
_VERSION = "2.17.337"
_OS_NAME = "Android"
_OS_VERSION = "4.3"
_DEVICE_NAME = "endeavoru"
_MANUFACTURER = "HTC"
_BUILD_VERSION = "IMM76D"
_AXOLOTL = True
def getVersion(self):
return self.__class__._VERSION
def getOSName(self):
return self.__class__._OS_NAME
def getOSVersion(self):
return self.__class__._OS_VERSION
def getDeviceName(self):
return self.__class__._DEVICE_NAME
def getBuildVersion(self):
return self.__class__._BUILD_VERSION
def getManufacturer(self):
return self.__class__._MANUFACTURER
def isAxolotlEnabled(self):
return self.__class__._AXOLOTL
def getToken(self, phoneNumber):
keyDecoded = bytearray(base64.b64decode(self.__class__._KEY))
sigDecoded = base64.b64decode(self.__class__._SIGNATURE)
clsDecoded = base64.b64decode(self.__class__._MD5_CLASSES)
data = sigDecoded + clsDecoded + phoneNumber.encode()
opad = bytearray()
ipad = bytearray()
for i in range(0, 64):
opad.append(0x5C ^ keyDecoded[i])
ipad.append(0x36 ^ keyDecoded[i])
hash = hashlib.sha1()
subHash = hashlib.sha1()
try:
subHash.update(ipad + data)
hash.update(opad + subHash.digest())
except TypeError:
subHash.update(bytes(ipad + data))
hash.update(bytes(opad + subHash.digest()))
result = base64.b64encode(hash.digest())
return result
yowsup-2.5.7/yowsup/env/env_s40.py 0000664 0000000 0000000 00000002271 13221545743 0017071 0 ustar 00root root 0000000 0000000 from .env import YowsupEnv
import hashlib
class S40YowsupEnv(YowsupEnv):
_VERSION = "2.16.12"
_OS_NAME= "S40"
_OS_VERSION = "14.26"
_DEVICE_NAME = "302"
_MANUFACTURER = "Nokia"
_TOKEN_STRING = "PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk1494451854337{phone}"
_AXOLOTL = True
def getVersion(self):
return self.__class__._VERSION
def getOSName(self):
return self.__class__._OS_NAME
def getOSVersion(self):
return self.__class__._OS_VERSION
def getDeviceName(self):
return self.__class__._DEVICE_NAME
def getManufacturer(self):
return self.__class__._MANUFACTURER
def isAxolotlEnabled(self):
return self.__class__._AXOLOTL
def getToken(self, phoneNumber):
return hashlib.md5(self.__class__._TOKEN_STRING.format(phone = phoneNumber).encode()).hexdigest()
def getUserAgent(self):
return self.__class__._USERAGENT_STRING.format(
WHATSAPP_VERSION = self.getVersion(),
OS_NAME = self.getOSName() + "Version",
OS_VERSION = self.getOSVersion(),
DEVICE_NAME = self.getDeviceName(),
MANUFACTURER = self.getManufacturer()
)
yowsup-2.5.7/yowsup/env/test_env_s40.py 0000664 0000000 0000000 00000000600 13221545743 0020122 0 ustar 00root root 0000000 0000000 import unittest
from yowsup.env import S40YowsupEnv
class S40YowsupEnvTest(unittest.TestCase):
def test_tokengen(self):
phone = "1234567"
S40YowsupEnv._TOKEN_STRING = "PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk1425519315543{phone}"
env = S40YowsupEnv()
token = env.getToken(phone)
self.assertEqual(token, 'e84e1f1477704159efd46f6f0781dbde')
yowsup-2.5.7/yowsup/layers/ 0000775 0000000 0000000 00000000000 13221545743 0015746 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/__init__.py 0000664 0000000 0000000 00000020775 13221545743 0020072 0 ustar 00root root 0000000 0000000 import unittest
import inspect
import threading
try:
import Queue
except ImportError:
import queue as Queue
class YowLayerEvent:
def __init__(self, name, **kwargs):
self.name = name
self.detached = False
if "detached" in kwargs:
del kwargs["detached"]
self.detached = True
self.args = kwargs
def isDetached(self):
return self.detached
def getName(self):
return self.name
def getArg(self, name):
return self.args[name] if name in self.args else None
class EventCallback(object):
def __init__(self, eventName):
self.eventName = eventName
def __call__(self, fn):
fn.event_callback = self.eventName
return fn
class YowLayer(object):
__upper = None
__lower = None
_props = {}
__detachedQueue = Queue.Queue()
# def __init__(self, upperLayer, lowerLayer):
# self.setLayers(upperLayer, lowerLayer)
def __init__(self):
self.setLayers(None, None)
self.interface = None
self.event_callbacks = {}
self.__stack = None
self.lock = threading.Lock()
members = inspect.getmembers(self, predicate=inspect.ismethod)
for m in members:
if hasattr(m[1], "event_callback"):
fname = m[0]
fn = m[1]
self.event_callbacks[fn.event_callback] = getattr(self, fname)
def getLayerInterface(self, YowLayerClass = None):
return self.interface if YowLayerClass is None else self.__stack.getLayerInterface(YowLayerClass)
def setStack(self, stack):
self.__stack = stack
def getStack(self):
return self.__stack
def setLayers(self, upper, lower):
self.__upper = upper
self.__lower = lower
def send(self, data):
self.toLower(data)
def receive(self, data):
self.toUpper(data)
def toUpper(self, data):
if self.__upper:
self.__upper.receive(data)
def toLower(self, data):
self.lock.acquire()
if self.__lower:
self.__lower.send(data)
self.lock.release()
def emitEvent(self, yowLayerEvent):
if self.__upper and not self.__upper.onEvent(yowLayerEvent):
if yowLayerEvent.isDetached():
yowLayerEvent.detached = False
self.getStack().execDetached(lambda : self.__upper.emitEvent(yowLayerEvent))
else:
self.__upper.emitEvent(yowLayerEvent)
def broadcastEvent(self, yowLayerEvent):
if self.__lower and not self.__lower.onEvent(yowLayerEvent):
if yowLayerEvent.isDetached():
yowLayerEvent.detached = False
self.getStack().execDetached(lambda:self.__lower.broadcastEvent(yowLayerEvent))
else:
self.__lower.broadcastEvent(yowLayerEvent)
'''return true to stop propagating the event'''
def onEvent(self, yowLayerEvent):
eventName = yowLayerEvent.getName()
if eventName in self.event_callbacks:
return self.event_callbacks[eventName](yowLayerEvent)
return False
def getProp(self, key, default = None):
return self.getStack().getProp(key, default)
def setProp(self, key, val):
return self.getStack().setProp(key, val)
class YowProtocolLayer(YowLayer):
def __init__(self, handleMap = None):
super(YowProtocolLayer, self).__init__()
self.handleMap = handleMap or {}
self.iqRegistry = {}
def receive(self, node):
if not self.processIqRegistry(node):
if node.tag in self.handleMap:
recv, _ = self.handleMap[node.tag]
if recv:
recv(node)
def send(self, entity):
if entity.getTag() in self.handleMap:
_, send = self.handleMap[entity.getTag()]
if send:
send(entity)
def entityToLower(self, entity):
#super(YowProtocolLayer, self).toLower(entity.toProtocolTreeNode())
self.toLower(entity.toProtocolTreeNode())
def isGroupJid(self, jid):
return "-" in jid
def raiseErrorForNode(self, node):
raise ValueError("Unimplemented notification type %s " % node)
def _sendIq(self, iqEntity, onSuccess = None, onError = None):
self.iqRegistry[iqEntity.getId()] = (iqEntity, onSuccess, onError)
self.toLower(iqEntity.toProtocolTreeNode())
def processIqRegistry(self, protocolTreeNode):
if protocolTreeNode.tag == "iq":
iq_id = protocolTreeNode["id"]
if iq_id in self.iqRegistry:
originalIq, successClbk, errorClbk = self.iqRegistry[iq_id]
del self.iqRegistry[iq_id]
if protocolTreeNode["type"] == "result" and successClbk:
successClbk(protocolTreeNode, originalIq)
elif protocolTreeNode["type"] == "error" and errorClbk:
errorClbk(protocolTreeNode, originalIq)
return True
return False
class YowParallelLayer(YowLayer):
def __init__(self, sublayers = None):
super(YowParallelLayer, self).__init__()
self.sublayers = sublayers or []
self.sublayers = tuple([sublayer() for sublayer in sublayers])
for s in self.sublayers:
#s.setLayers(self, self)
s.toLower = self.toLower
s.toUpper = self.toUpper
s.broadcastEvent = self.subBroadcastEvent
s.emitEvent = self.subEmitEvent
def getLayerInterface(self, YowLayerClass):
for s in self.sublayers:
if s.__class__ == YowLayerClass:
return s.getLayerInterface()
def setStack(self, stack):
super(YowParallelLayer, self).setStack(stack)
for s in self.sublayers:
s.setStack(self.getStack())
def receive(self, data):
for s in self.sublayers:
s.receive(data)
def send(self, data):
for s in self.sublayers:
s.send(data)
def subBroadcastEvent(self, yowLayerEvent):
self.onEvent(yowLayerEvent)
self.broadcastEvent(yowLayerEvent)
def subEmitEvent(self, yowLayerEvent):
self.onEvent(yowLayerEvent)
self.emitEvent(yowLayerEvent)
def onEvent(self, yowLayerEvent):
stopEvent = False
for s in self.sublayers:
stopEvent = stopEvent or s.onEvent(yowLayerEvent)
return stopEvent
def __str__(self):
return " - ".join([l.__str__() for l in self.sublayers])
class YowLayerInterface(object):
def __init__(self, layer):
self._layer = layer
class YowLayerTest(unittest.TestCase):
def __init__(self, *args):
super(YowLayerTest, self).__init__(*args)
self.upperSink = []
self.lowerSink = []
self.toUpper = self.receiveOverrider
self.toLower = self.sendOverrider
self.upperEventSink = []
self.lowerEventSink = []
self.emitEvent = self.emitEventOverrider
self.broadcastEvent = self.broadcastEventOverrider
def receiveOverrider(self, data):
self.upperSink.append(data)
def sendOverrider(self, data):
self.lowerSink.append(data)
def emitEventOverrider(self, event):
self.upperEventSink.append(event)
def broadcastEventOverrider(self, event):
self.lowerEventSink.append(event)
def assert_emitEvent(self, event):
self.emitEvent(event)
try:
self.assertEqual(event, self.upperEventSink.pop())
except IndexError:
raise AssertionError("Event '%s' was not emited through this layer" % (event.getName()))
def assert_broadcastEvent(self, event):
self.broadcastEvent(event)
try:
self.assertEqual(event, self.lowerEventSink.pop())
except IndexError:
raise AssertionError("Event '%s' was not broadcasted through this layer" % (event.getName()))
class YowProtocolLayerTest(YowLayerTest):
def assertSent(self, entity):
self.send(entity)
try:
self.assertEqual(entity.toProtocolTreeNode(), self.lowerSink.pop())
except IndexError:
raise AssertionError("Entity '%s' was not sent through this layer" % (entity.getTag()))
def assertReceived(self, entity):
node = entity.toProtocolTreeNode()
self.receive(node)
try:
self.assertEqual(node, self.upperSink.pop().toProtocolTreeNode())
except IndexError:
raise AssertionError("'%s' was not received through this layer" % (entity.getTag()))
yowsup-2.5.7/yowsup/layers/auth/ 0000775 0000000 0000000 00000000000 13221545743 0016707 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/auth/__init__.py 0000664 0000000 0000000 00000000242 13221545743 0021016 0 ustar 00root root 0000000 0000000 from .layer_crypt import YowCryptLayer
from .layer_authentication import YowAuthenticationProtocolLayer
from .autherror import AuthError
#import protocolentities
yowsup-2.5.7/yowsup/layers/auth/autherror.py 0000664 0000000 0000000 00000000044 13221545743 0021272 0 ustar 00root root 0000000 0000000 class AuthError(Exception):
pass yowsup-2.5.7/yowsup/layers/auth/keystream.py 0000664 0000000 0000000 00000007570 13221545743 0021276 0 ustar 00root root 0000000 0000000 import hashlib, hmac, sys
from struct import pack
from operator import xor
from itertools import starmap
class RC4:
def __init__(self, key, drop):
self.s = []
self.i = 0;
self.j = 0;
self.s = [0] * 256
for i in range(0, len(self.s)):
self.s[i] = i
for i in range(0, len(self.s)):
self.j = (self.j + self.s[i] + key[i % len(key)]) % 256
RC4.swap(self.s, i, self.j)
self.j = 0;
self.cipher(bytearray(drop), 0, drop)
def cipher(self, data, offset, length):
while True:
num = length
length = num - 1
if num == 0: break
self.i = (self.i+1) % 256
self.j = (self.j + self.s[self.i]) % 256
RC4.swap(self.s, self.i, self.j)
num2 = offset
offset = num2 + 1
data[num2] = (data[num2] ^ self.s[(self.s[self.i] + self.s[self.j]) % 256])
@staticmethod
def swap(arr, i, j):
tmp = arr[i]
arr[i] = arr[j]
arr[j] = tmp
class KeyStream:
def __init__(self, key, macKey):
self.key = key if sys.version_info < (3, 0) else bytes(key)
self.rc4 = RC4(self.key, 0x300)
self.macKey = str(macKey) if sys.version_info < (3, 0) else bytes(macKey)
self.seq = 0
def computeMac(self, bytes_buffer, int_offset, int_length):
mac = hmac.new(self.macKey, None, hashlib.sha1)
updateData = bytes_buffer[int_offset:] + bytearray([self.seq >> 24, (self.seq >> 16) % 256, (self.seq >> 8) % 256, self.seq % 256])
try:
mac.update(updateData)
except TypeError: #python3 support
mac.update(bytes(updateData))
self.seq += 1
return bytearray(mac.digest())
def decodeMessage(self, bufdata, macOffset, offset, length):
buf = bufdata[:-4]
hashed = bufdata[-4:]
numArray = self.computeMac(buf, 0, len(buf))
num = 0
while num < 4:
if numArray[macOffset + num] == hashed[num]:
num += 1
else:
raise Exception("INVALID MAC")
self.rc4.cipher(buf, 0, len(buf))
return buf
def encodeMessage(self, buf, macOffset, offset, length):
self.rc4.cipher(buf, offset, length)
mac = self.computeMac(buf, offset, length)
output = buf[0:macOffset] + mac[0:4] + buf[macOffset+4:]
return output
@staticmethod
def generateKeys(password, nonce):
resultBytes = []
for i in range(1, 5):
currNonce = nonce + bytearray([i])
resultBytes.append(KeyStream.pbkdf2(password, currNonce, 2, 20))
return resultBytes
#@staticmethod ##use if drop python-2.6 support
#def pbkdf2( password, salt, itercount, keylen):
# return bytearray(hashlib.pbkdf2_hmac('sha1', password, salt, itercount, keylen))
@staticmethod
def pbkdf2( password, salt, itercount, keylen, hashfn = hashlib.sha1 ):
def pbkdf2_F( h, salt, itercount, blocknum ):
def prf( h, data ):
hm = h.copy()
try:
hm.update(bytearray(data))
except TypeError: #python 3 support
hm.update(bytes(data))
d = hm.digest()
return bytearray(d)
U = prf( h, salt + pack('>i',blocknum ) )
T = U
for i in range(2, itercount + 1):
U = prf( h, U )
T = starmap(xor, zip(T, U))
return T
digest_size = hashfn().digest_size
l = int(keylen / digest_size)
if keylen % digest_size != 0:
l += 1
h = hmac.new(bytes(password), None, hashfn )
T = bytearray()
for i in range(1, l+1):
tmp = pbkdf2_F( h, salt, itercount, i )
T.extend(tmp)
return T[0: keylen] yowsup-2.5.7/yowsup/layers/auth/layer_authentication.py 0000664 0000000 0000000 00000014420 13221545743 0023475 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers import YowLayerEvent, YowProtocolLayer, EventCallback
from .keystream import KeyStream
from yowsup.common.tools import TimeTools
from .layer_crypt import YowCryptLayer
from yowsup.layers.network import YowNetworkLayer
from .autherror import AuthError
from .protocolentities import *
from yowsup.common.tools import StorageTools
from yowsup.env import YowsupEnv
from .layer_interface_authentication import YowAuthenticationProtocolLayerInterface
from .protocolentities import StreamErrorProtocolEntity
import base64
class YowAuthenticationProtocolLayer(YowProtocolLayer):
EVENT_LOGIN = "org.openwhatsapp.yowsup.event.auth.login"
EVENT_AUTHED = "org.openwhatsapp.yowsup.event.auth.authed"
PROP_CREDENTIALS = "org.openwhatsapp.yowsup.prop.auth.credentials"
PROP_PASSIVE = "org.openwhatsapp.yowsup.prop.auth.passive"
def __init__(self):
handleMap = {
"stream:features": (self.handleStreamFeatures, None),
"failure": (self.handleFailure, None),
"success": (self.handleSuccess, None),
"challenge": (self.handleChallenge, None),
"stream:error": (self.handleStreamError, None),
}
super(YowAuthenticationProtocolLayer, self).__init__(handleMap)
self.interface = YowAuthenticationProtocolLayerInterface(self)
self.credentials = None #left for backwards-compat
self._credentials = None #new style set
def __str__(self):
return "Authentication Layer"
def __getCredentials(self, credentials = None):
u, pb64 = credentials or self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)
if type(pb64) is str:
pb64 = pb64.encode()
password = base64.b64decode(pb64)
return (u, bytearray(password))
def setCredentials(self, credentials):
self.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, credentials) #keep for now
self._credentials = self.__getCredentials(credentials)
def getUsername(self, full = False):
if self._credentials:
return self._credentials[0] if not full else ("%s@%s" % (self._credentials[0], YowConstants.WHATSAPP_SERVER))
else:
prop = self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)
return prop[0] if prop else None
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, yowLayerEvent):
self.login()
## general methods
def login(self):
self.credentials = self._credentials or self.__getCredentials()
self._sendFeatures()
self._sendAuth()
###recieved node handlers handlers
def handleStreamFeatures(self, node):
nodeEntity = StreamFeaturesProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(nodeEntity)
def handleSuccess(self, node):
if(node.data != None): StorageTools.writeNonce(self.credentials[0],node.data)
successEvent = YowLayerEvent(self.__class__.EVENT_AUTHED, passive = self.getProp(self.__class__.PROP_PASSIVE))
self.broadcastEvent(successEvent)
nodeEntity = SuccessProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(nodeEntity)
def handleFailure(self, node):
nodeEntity = FailureProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(nodeEntity)
self.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT, reason = "Authentication Failure"))
raise AuthError(nodeEntity.getReason())
def handleChallenge(self, node):
nodeEntity = ChallengeProtocolEntity.fromProtocolTreeNode(node)
self._sendResponse(nodeEntity.getNonce())
def handleStreamError(self, node):
nodeEntity = StreamErrorProtocolEntity.fromProtocolTreeNode(node)
errorType = nodeEntity.getErrorType()
if not errorType:
raise AuthError("Unhandled stream:error node:\n%s" % node)
self.toUpper(nodeEntity)
##senders
def _sendFeatures(self):
self.entityToLower(StreamFeaturesProtocolEntity([]))
def _sendAuth(self):
passive = self.getProp(self.__class__.PROP_PASSIVE, False)
nonce = StorageTools.getNonce(self.credentials[0])
if nonce == None:
self.entityToLower(AuthProtocolEntity(self.credentials[0], passive=passive))
else:
inputKey, outputKey, authBlob = self.generateAuthBlob(nonce)
#to prevent enr whole response
self.broadcastEvent(YowLayerEvent(YowCryptLayer.EVENT_KEYS_READY, keys = (inputKey, None)))
self.entityToLower(AuthProtocolEntity(self.credentials[0], passive=passive, nonce=authBlob))
self.broadcastEvent(YowLayerEvent(YowCryptLayer.EVENT_KEYS_READY, keys = (inputKey, outputKey)))
def _sendResponse(self,nonce):
inputKey, outputKey, authBlob = self.generateAuthBlob(nonce)
responseEntity = ResponseProtocolEntity(authBlob)
#to prevent enr whole response
self.broadcastEvent(YowLayerEvent(YowCryptLayer.EVENT_KEYS_READY, keys = (inputKey, None)))
self.entityToLower(responseEntity)
self.broadcastEvent(YowLayerEvent(YowCryptLayer.EVENT_KEYS_READY, keys = (inputKey, outputKey)))
#YowCryptLayer.setProp("outputKey", outputKey)
def generateAuthBlob(self, nonce):
keys = KeyStream.generateKeys(self.credentials[1], nonce)
currentEnv = YowsupEnv.getCurrent()
inputKey = KeyStream(keys[2], keys[3])
outputKey = KeyStream(keys[0], keys[1])
#YowCryptLayer.setProp("inputKey", inputKey)
nums = bytearray(4)
#nums = [0] * 4
username_bytes = list(map(ord, self.credentials[0]))
nums.extend(username_bytes)
nums.extend(nonce)
utcNow = str(int(TimeTools.utcTimestamp()))
time_bytes = list(map(ord, utcNow))
nums.extend(time_bytes)
strCat = "\x00\x00\x00\x00\x00\x00\x00\x00"
strCat += currentEnv.getOSVersion() + "\x00"
strCat += currentEnv.getManufacturer() + "\x00"
strCat += currentEnv.getDeviceName() + "\x00"
strCat += currentEnv.getBuildVersion()
nums.extend(list(map(ord, strCat)))
encoded = outputKey.encodeMessage(nums, 0, 4, len(nums) - 4)
authBlob = "".join(map(chr, encoded))
return (inputKey, outputKey, authBlob)
yowsup-2.5.7/yowsup/layers/auth/layer_crypt.py 0000664 0000000 0000000 00000004073 13221545743 0021622 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, EventCallback
from yowsup.layers.network import YowNetworkLayer
class YowCryptLayer(YowLayer):
'''
send: bytearray -> bytearray
receive: bytearray -> bytearray
'''
EVENT_KEYS_READY = "org.openwhatsapp.yowsup.crypt.keys"
def __init__(self):
super(YowCryptLayer, self).__init__()
self.keys = (None,None)
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, yowLayerEvent):
self.keys = (None,None)
@EventCallback(EVENT_KEYS_READY)
def onKeysReady(self, yowLayerEvent):
self.keys = yowLayerEvent.getArg("keys")
return True
def send(self, data):
outputKey = self.keys[1]
length1 = len(data)
if length1 > 1:
if outputKey:
length1 += 4
buf = outputKey.encodeMessage(data, len(data), 0, len(data))
res = [0,0,0]
res.extend(buf)
res[0] = ((8 << 4) | (length1 & 16711680) >> 16) % 256
res[1] = ((length1 & 65280) >> 8) % 256
res[2] = (length1 & 255) % 256
data = res
else:
prep = [0,0,0]
prep.extend(data)
prep[0] = ((0 << 4) | (length1 & 16711680) >> 16) % 256
prep[1] = ((length1 & 65280) >> 8) % 256
prep[2] = (length1 & 255) % 256
data = prep
self.toLower(bytearray(data))
def receive(self, data):
inputKey = self.keys[0]
metaData = data[:3]
payload = bytearray(data[3:])
firstByte = metaData[0]
stanzaFlag = (firstByte & 0xF0) >> 4
stanzaSize = ((metaData[1] << 8) + metaData[2]) | ((firstByte & 0x0F) << 16)
isEncrypted = ((stanzaFlag & 8) != 0)
if inputKey and isEncrypted:
toDecode = data[3:]
payload = inputKey.decodeMessage(payload, 0, 4, len(payload) - 4)
self.toUpper(payload)
def __str__(self):
return "Crypt Layer" yowsup-2.5.7/yowsup/layers/auth/layer_interface_authentication.py 0000664 0000000 0000000 00000000453 13221545743 0025516 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayerInterface
class YowAuthenticationProtocolLayerInterface(YowLayerInterface):
def setCredentials(self, phone, password):
self._layer.setCredentials((phone, password))
def getUsername(self, full = False):
return self._layer.getUsername(full)
yowsup-2.5.7/yowsup/layers/auth/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0022315 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/auth/protocolentities/__init__.py 0000664 0000000 0000000 00000000505 13221545743 0024426 0 ustar 00root root 0000000 0000000 from .auth import AuthProtocolEntity
from .challenge import ChallengeProtocolEntity
from .response import ResponseProtocolEntity
from .stream_features import StreamFeaturesProtocolEntity
from .success import SuccessProtocolEntity
from .failure import FailureProtocolEntity
from .stream_error import StreamErrorProtocolEntity
yowsup-2.5.7/yowsup/layers/auth/protocolentities/auth.py 0000664 0000000 0000000 00000001674 13221545743 0023640 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class AuthProtocolEntity(ProtocolEntity):
def __init__(self, user, mechanism = "WAUTH-2", passive = False, nonce = None):
super(AuthProtocolEntity, self).__init__("auth")
self.user = user
self.mechanism = mechanism
self.passive = passive
self.nonce = nonce
def toProtocolTreeNode(self):
attributes = {
"user" : self.user,
"mechanism" : self.mechanism,
"passive" : "true" if self.passive else "false"
}
return self._createProtocolTreeNode(attributes, children = None, data = self.nonce)
@staticmethod
def fromProtocolTreeNode(node):
return AuthProtocolEntity(
node.getAttributeValue("user"),
node.getAttributeValue("mechanism"),
node.getAttributeValue("passive") != "false",
node.getData()
) yowsup-2.5.7/yowsup/layers/auth/protocolentities/challenge.py 0000664 0000000 0000000 00000001443 13221545743 0024613 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class ChallengeProtocolEntity(ProtocolEntity):
def __init__(self, nonce):
super(ChallengeProtocolEntity, self).__init__("challenge")
self.nonce = nonce
def getNonce(self):
return self.nonce
def toProtocolTreeNode(self):
#return self._createProtocolTreeNode({}, children = None, data = self.nonce)
return self._createProtocolTreeNode({}, children = [], data = "".join(map(chr, self.nonce)))
def __str__(self):
out = "Challenge\n"
out += "Nonce: %s\n" % self.nonce
return out
@staticmethod
def fromProtocolTreeNode(node):
nonce = list(map(ord,node.getData()))
entity = ChallengeProtocolEntity(bytearray(nonce))
return entity
yowsup-2.5.7/yowsup/layers/auth/protocolentities/failure.py 0000664 0000000 0000000 00000001254 13221545743 0024320 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class FailureProtocolEntity(ProtocolEntity):
def __init__(self, reason):
super(FailureProtocolEntity, self).__init__("failure")
self.reason = reason
def __str__(self):
out = "Failure:\n"
out += "Reason: %s\n" % self.reason
return out
def getReason(self):
return self.reason
def toProtocolTreeNode(self):
reasonNode = ProtocolTreeNode(self.reason, {})
return self._createProtocolTreeNode({}, children = [reasonNode])
@staticmethod
def fromProtocolTreeNode(node):
return FailureProtocolEntity( node.getAllChildren()[0].tag ) yowsup-2.5.7/yowsup/layers/auth/protocolentities/response.py 0000664 0000000 0000000 00000001103 13221545743 0024520 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class ResponseProtocolEntity(ProtocolEntity):
def __init__(self, data, xmlns = "urn:ietf:params:xml:ns:xmpp-sasl"):
super(ResponseProtocolEntity, self).__init__("response")
self.xmlns = xmlns
self.data = data
def toProtocolTreeNode(self):
return self._createProtocolTreeNode({"xmlns": self.xmlns}, children = None, data = self.data)
@staticmethod
def fromProtocolTreeNode(node):
return ResponseProtocolEntity(node.getData(), node.getAttributeValue("xmlns")) yowsup-2.5.7/yowsup/layers/auth/protocolentities/stream_error.py 0000664 0000000 0000000 00000003366 13221545743 0025403 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class StreamErrorProtocolEntity(ProtocolEntity):
TYPE_CONFLICT = "conflict"
'''
Replaced by new connection
'''
TYPE_ACK = "ack"
'''
'''
TYPE_XML_NOT_WELL_FORMED = "xml-not-well-formed"
'''
'''
TYPES = (TYPE_CONFLICT, TYPE_ACK, TYPE_XML_NOT_WELL_FORMED)
def __init__(self, data = None):
super(StreamErrorProtocolEntity, self).__init__("stream:error")
data = data or {}
self.setErrorData(data)
def setErrorData(self, data):
self.data = data
def getErrorData(self):
return self.data
def getErrorType(self):
for k in self.data.keys():
if k in self.__class__.TYPES:
return k
def __str__(self):
out = "Stream Error type: %s\n" % self.getErrorType()
out += "%s" % self.getErrorData()
out += "\n"
return out
def toProtocolTreeNode(self):
node = super(StreamErrorProtocolEntity, self).toProtocolTreeNode()
type = self.getErrorType()
node.addChild(ProtocolTreeNode(type))
if type == self.__class__.TYPE_CONFLICT and "text" in self.data:
node.addChild(ProtocolTreeNode("text", data=self.data["text"]))
return node
@staticmethod
def fromProtocolTreeNode(protocolTreeNode):
data = {}
for child in protocolTreeNode.getAllChildren():
data[child.tag] = child.data
return StreamErrorProtocolEntity(data)
yowsup-2.5.7/yowsup/layers/auth/protocolentities/stream_features.py 0000664 0000000 0000000 00000001273 13221545743 0026063 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class StreamFeaturesProtocolEntity(ProtocolEntity):
def __init__(self, features = None):
super(StreamFeaturesProtocolEntity, self).__init__("stream:features")
self.setFeatures(features)
def setFeatures(self, features = None):
self.features = features or []
def toProtocolTreeNode(self):
featureNodes = [ProtocolTreeNode(feature) for feature in self.features]
return self._createProtocolTreeNode({}, children = featureNodes, data = None)
@staticmethod
def fromProtocolTreeNode(node):
return StreamFeaturesProtocolEntity([fnode.tag for fnode in node.getAllChildren()]) yowsup-2.5.7/yowsup/layers/auth/protocolentities/success.py 0000664 0000000 0000000 00000003173 13221545743 0024343 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class SuccessProtocolEntity(ProtocolEntity):
def __init__(self, status, kind, creation, expiration, props, t, nonce = None):
super(SuccessProtocolEntity, self).__init__("success")
self.status = status
self.kind = kind
self.creation = int(creation)
self.expiration = int(expiration)
self.props = props
self.nonce = nonce
self.t = int(t) ##whatever that is !
def __str__(self):
out = "Account:\n"
out += "Status: %s\n" % self.status
out += "Kind: %s\n" % self.kind
out += "Creation: %s\n" % self.creation
out += "Expiration: %s\n" % self.expiration
out += "Props: %s\n" % self.props
out += "t: %s\n" % self.t
return out
def toProtocolTreeNode(self):
attributes = {
"status" : self.status,
"kind" : self.kind,
"creation" : str(self.creation),
"expiration" : str(self.expiration),
"props" : self.props,
"t" : str(self.t)
}
return self._createProtocolTreeNode(attributes, children = None, data = self.nonce)
@staticmethod
def fromProtocolTreeNode(node):
return SuccessProtocolEntity(
node.getAttributeValue("status"),
node.getAttributeValue("kind"),
node.getAttributeValue("creation"),
node.getAttributeValue("expiration"),
node.getAttributeValue("props"),
node.getAttributeValue("t"),
node.getData()
) yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_auth.py 0000664 0000000 0000000 00000000667 13221545743 0024700 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities import AuthProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class AuthProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = AuthProtocolEntity
self.node = ProtocolTreeNode("auth", {"user": "testuser", "mechanism": "WAUTH-2", "passive": "false"}) yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_challenge.py 0000664 0000000 0000000 00000001021 13221545743 0025642 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities.challenge import ChallengeProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class ChallengeProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = ChallengeProtocolEntity
attribs = {}
childNodes = []
data = "dummydata"
self.node = ProtocolTreeNode("challenge", attribs, [], data) yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_failure.py 0000664 0000000 0000000 00000000666 13221545743 0025365 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities.failure import FailureProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class FailureProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = FailureProtocolEntity
self.node = ProtocolTreeNode("failure", {}, [ProtocolTreeNode("not-authorized", {})]) yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_response.py 0000664 0000000 0000000 00000000777 13221545743 0025577 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities.response import ResponseProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class ResponseProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = ResponseProtocolEntity
attribs = {
"xmlns": "urn:ietf:params:xml:ns:xmpp-sasl"
}
self.node = ProtocolTreeNode("response", attribs, None, "dummydata") yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_stream_features.py 0000664 0000000 0000000 00000001046 13221545743 0027120 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities.stream_features import StreamFeaturesProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class StreamFeaturesProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = StreamFeaturesProtocolEntity
attribs = {
}
childNode = ProtocolTreeNode("receipt_acks", {}, None, None)
self.node = ProtocolTreeNode("stream:features", attribs, [childNode]) yowsup-2.5.7/yowsup/layers/auth/protocolentities/test_success.py 0000664 0000000 0000000 00000001176 13221545743 0025403 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth.protocolentities.success import SuccessProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class SuccessProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = SuccessProtocolEntity
attribs = {
"status": "active",
"kind": "free",
"creation": "1234",
"expiration": "1446578937",
"props": "2",
"t": "1415470561"
}
self.node = ProtocolTreeNode("success", attribs, None, "dummydata") yowsup-2.5.7/yowsup/layers/auth/test_authenticator.py 0000664 0000000 0000000 00000002660 13221545743 0023176 0 ustar 00root root 0000000 0000000 from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers import YowLayerEvent, YowLayerTest
from yowsup.layers.auth.protocolentities import StreamFeaturesProtocolEntity,AuthProtocolEntity, ChallengeProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.stacks import YowStack
import base64
# from unittest.mock import MagicMock
class AuthenticationProtocolLayerTest(YowLayerTest, YowAuthenticationProtocolLayer):
def setUp(self):
#YowAuthenticatorLayer.__init__(self)
super(YowAuthenticationProtocolLayer, self).__init__()
dummyStack = YowStack()
self.setStack(dummyStack)
self.credentials = ("dummyusername", bytearray("password", "latin-1"))
dummyStack.setProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS, self.credentials)
#ticatorLayer.setProp("credentials", self.credentials)
def test_streamfeatures(self):
self._sendFeatures()
self.assertEqual(self.lowerSink.pop(), StreamFeaturesProtocolEntity([]).toProtocolTreeNode())
def test_auth(self):
self._sendAuth()
self.assertEqual(self.lowerSink.pop(), AuthProtocolEntity(self.credentials[0]).toProtocolTreeNode())
def test_handle_challenge(self):
node = ProtocolTreeNode("challenge", {}, None, "salt")
self.handleChallenge(node)
def test_login_onconnected(self):
self.onEvent(YowLayerEvent("network.state.connected"))
yowsup-2.5.7/yowsup/layers/auth/test_crypt.py 0000664 0000000 0000000 00000002513 13221545743 0021462 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayerEvent, YowLayerTest
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.auth import YowCryptLayer
from yowsup.layers.auth.keystream import KeyStream
class CryptLayerTest(YowLayerTest, YowCryptLayer):
def setUp(self):
YowCryptLayer.__init__(self)
self.password = bytearray(list(map(ord,"password")))
self.salt = bytearray(list(map(ord,"salt")))
self.username = "username"
self.inputMessage = bytearray([0,0,0,0, ord('t'), ord('a'), ord('r'), ord('e'), ord('k')])
self.inputMessageCrypted = bytearray(b'\x80\x00\r)\x99\xbe_\xee\x98\xecV<\x9d\x0c\xb7r')
keys = [
bytearray(b'>\xd5\x8a\xecB\xdb\xc8\xd4}\x98\x9aBa\x89\x9fC\x08\xdcp\x8d'),
bytearray(b'\xd3;\xda:\x8f\x94CX\xe4;\xbb\xcc"W\x83\xe0m\xba\xe0\xd1'),
bytearray(b'\x92w{\xc2\x04~\x08;\x81w\xb7h3\xb8\xc4t\xbd\xed\xf7q'),
bytearray(b'.\xc7\xe4\x15\x1a\xa0\xfd\x98\xc0\xea\xefs{\r7E\xa6\xec\xd5\xfb')
]
inputKey = KeyStream(keys[2], keys[3])
outputKey = KeyStream(keys[0], keys[1])
self.onEvent(YowLayerEvent(YowCryptLayer.EVENT_KEYS_READY, keys = (inputKey, outputKey)))
def test_00send(self):
self.send(self.inputMessage)
self.assertEqual(self.lowerSink.pop(), self.inputMessageCrypted)
yowsup-2.5.7/yowsup/layers/auth/test_keystream.py 0000664 0000000 0000000 00000004405 13221545743 0022327 0 ustar 00root root 0000000 0000000 import unittest
from yowsup.layers.auth.keystream import KeyStream
class KeyStreamTest(unittest.TestCase):
def setUp(self):
self.password = bytearray(list(map(ord,"password")))
self.salt = bytearray(list(map(ord,"salt")))
self.keysTarget = [
bytearray(b'>\xd5\x8a\xecB\xdb\xc8\xd4}\x98\x9aBa\x89\x9fC\x08\xdcp\x8d'),
bytearray(b'\xd3;\xda:\x8f\x94CX\xe4;\xbb\xcc"W\x83\xe0m\xba\xe0\xd1'),
bytearray(b'\x92w{\xc2\x04~\x08;\x81w\xb7h3\xb8\xc4t\xbd\xed\xf7q'),
bytearray(b'.\xc7\xe4\x15\x1a\xa0\xfd\x98\xc0\xea\xefs{\r7E\xa6\xec\xd5\xfb')
]
self.pbkdbf2_res = bytearray(b'\xeal\x01M\xc7-o\x8c\xcd\x1e\xd9*\xce\x1dA\xf0\xd8\xde\x89W')
self.inputMessage = bytearray([0,0,0,0, ord('t'), ord('a'), ord('r'), ord('e'), ord('k')])
self.inputMessageComputedMac = bytearray(b'\xec\x82q\xab\x9f\x8d;\xac\x83\xc5X\xbb\xb6u\x1c\xb0\xd2\x82=`')
self.inputMessageRC4Ciphered = bytearray(b'\x00\x00\x00\x00\xf4&-\x0c\xbc')
def test_generateKeys(self):
keys = KeyStream.generateKeys(self.password, self.salt)
self.assertEqual(keys, self.keysTarget)
def test_pbkdf2(self):
result = KeyStream.pbkdf2(self.password, self.salt, 2, 20)
result = bytearray(result)
self.assertEqual(result, self.pbkdbf2_res)
def test_computemac(self):
keys = self.keysTarget
kstream = KeyStream(keys[2], keys[3])
res = kstream.computeMac(self.inputMessage, 4, len(self.inputMessage) - 4)
self.assertEqual(res, self.inputMessageComputedMac)
def test_rc4(self):
keys = self.keysTarget
kstream = KeyStream(keys[2], keys[3])
kstream.rc4.cipher(self.inputMessage, 4, len(self.inputMessage) - 4)
self.assertEqual(self.inputMessage, self.inputMessageRC4Ciphered)
def test_encodeMessage(self):
keys = self.keysTarget
kstream = KeyStream(keys[2], keys[3])
encoded = kstream.encodeMessage(self.inputMessage, 0, 4, len(self.inputMessage) - 4)
def test_manyEncode(self):
keys = self.keysTarget
kstream = KeyStream(keys[2], keys[3])
for i in range(0, 300):
encoded = kstream.encodeMessage(self.inputMessage, 0, 4, len(self.inputMessage) - 4) yowsup-2.5.7/yowsup/layers/axolotl/ 0000775 0000000 0000000 00000000000 13221545743 0017430 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/axolotl/__init__.py 0000664 0000000 0000000 00000000207 13221545743 0021540 0 ustar 00root root 0000000 0000000 from .layer_send import AxolotlSendLayer
from .layer_control import AxolotlControlLayer
from .layer_receive import AxolotlReceivelayer
yowsup-2.5.7/yowsup/layers/axolotl/layer_base.py 0000664 0000000 0000000 00000006101 13221545743 0022106 0 ustar 00root root 0000000 0000000 from yowsup.layers.axolotl.store.sqlite.liteaxolotlstore import LiteAxolotlStore
from yowsup.layers import YowProtocolLayer
from yowsup.common.tools import StorageTools
from yowsup.layers.auth.layer_authentication import YowAuthenticationProtocolLayer
from yowsup.layers.axolotl.protocolentities import *
from axolotl.sessionbuilder import SessionBuilder
from axolotl.untrustedidentityexception import UntrustedIdentityException
from yowsup.layers.axolotl.props import PROP_IDENTITY_AUTOTRUST
import logging
logger = logging.getLogger(__name__)
class AxolotlBaseLayer(YowProtocolLayer):
_DB = "axolotl.db"
def __init__(self):
super(AxolotlBaseLayer, self).__init__()
self._store = None
self.skipEncJids = []
def onNewStoreSet(self, store):
pass
def send(self, node):
pass
def receive(self, node):
self.processIqRegistry(node)
@property
def store(self):
try:
if self._store is None:
self.store = LiteAxolotlStore(
StorageTools.constructPath(
self.getProp(
YowAuthenticationProtocolLayer.PROP_CREDENTIALS)[0],
self.__class__._DB
)
)
return self._store
except AttributeError:
return None
@store.setter
def store(self, store):
self._store = store
self.onNewStoreSet(self._store)
def getKeysFor(self, jids, resultClbk, errorClbk = None):
def onSuccess(resultNode, getKeysEntity):
entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
resultJids = entity.getJids()
successJids = []
errorJids = {} #jid -> exception
for jid in getKeysEntity.getJids():
if jid not in resultJids:
self.skipEncJids.append(jid)
continue
recipient_id = jid.split('@')[0]
preKeyBundle = entity.getPreKeyBundleFor(jid)
sessionBuilder = SessionBuilder(self.store, self.store, self.store, self.store, recipient_id, 1)
try:
sessionBuilder.processPreKeyBundle(preKeyBundle)
successJids.append(jid)
except UntrustedIdentityException as e:
if self.getProp(PROP_IDENTITY_AUTOTRUST, False):
logger.warning("Autotrusting identity for %s" % e.getName())
self.store.saveIdentity(e.getName(), e.getIdentityKey())
successJids.append(jid)
else:
errorJids[jid] = e
logger.error(e)
logger.warning("Ignoring message with untrusted identity")
resultClbk(successJids, errorJids)
def onError(errorNode, getKeysEntity):
if errorClbk:
errorClbk(errorNode, getKeysEntity)
entity = GetKeysIqProtocolEntity(jids)
self._sendIq(entity, onSuccess, onError=onError)
yowsup-2.5.7/yowsup/layers/axolotl/layer_control.py 0000664 0000000 0000000 00000013732 13221545743 0022664 0 ustar 00root root 0000000 0000000 from .layer_base import AxolotlBaseLayer
from yowsup.layers import YowLayerEvent, EventCallback
from yowsup.layers.network.layer import YowNetworkLayer
from axolotl.util.keyhelper import KeyHelper
from yowsup.layers.axolotl.protocolentities import *
from yowsup.layers.auth.layer_authentication import YowAuthenticationProtocolLayer
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
from axolotl.util.hexutil import HexUtil
from axolotl.ecc.curve import Curve
import logging
import binascii
import sys
logger = logging.getLogger(__name__)
class AxolotlControlLayer(AxolotlBaseLayer):
_STATE_INIT = 0
_STATE_GENKEYS = 1
_STATE_HASKEYS = 2
_COUNT_PREKEYS = 200
EVENT_PREKEYS_SET = "org.openwhatsapp.yowsup.events.axololt.setkeys"
def __init__(self):
super(AxolotlControlLayer, self).__init__()
self.state = self.__class__._STATE_INIT
def onNewStoreSet(self, store):
super(AxolotlControlLayer, self).onNewStoreSet(store)
if store is not None:
self.state = self.__class__._STATE_HASKEYS if store.getLocalRegistrationId() is not None \
else self.__class__._STATE_INIT
def send(self, node):
self.toLower(node)
def receive(self, protocolTreeNode):
"""
:type protocolTreeNode: ProtocolTreeNode
"""
if not self.processIqRegistry(protocolTreeNode):
if protocolTreeNode.tag == "notification" and protocolTreeNode["type"] == "encrypt":
self.onEncryptNotification(protocolTreeNode)
return
self.toUpper(protocolTreeNode)
def isInitState(self):
return self.store == None or self.state == self.__class__._STATE_INIT
def isGenKeysState(self):
return self.state == self.__class__._STATE_GENKEYS
def onEncryptNotification(self, protocolTreeNode):
entity = EncryptNotification.fromProtocolTreeNode(protocolTreeNode)
ack = OutgoingAckProtocolEntity(protocolTreeNode["id"], "notification", protocolTreeNode["type"], protocolTreeNode["from"])
self.toLower(ack.toProtocolTreeNode())
self.sendKeys(fresh=False, countPreKeys = self.__class__._COUNT_PREKEYS - entity.getCount())
@EventCallback(EVENT_PREKEYS_SET)
def onPreKeysSet(self, yowLayerEvent):
self.sendKeys(fresh=False)
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, yowLayerEvent):
if self.isInitState():
self.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True)
@EventCallback(YowAuthenticationProtocolLayer.EVENT_AUTHED)
def onAuthed(self, yowLayerEvent):
if yowLayerEvent.getArg("passive") and self.isInitState():
logger.info("Axolotl layer is generating keys")
self.sendKeys()
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
def onDisconnected(self, yowLayerEvent):
if self.isGenKeysState():
#we requested this disconnect in this layer to switch off passive
#no need to traverse it to upper layers?
self.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, False)
self.state = self.__class__._STATE_HASKEYS
self.getLayerInterface(YowNetworkLayer).connect()
else:
self.store = None
### keys set and get
def sendKeys(self, fresh = True, countPreKeys = _COUNT_PREKEYS):
identityKeyPair = KeyHelper.generateIdentityKeyPair() if fresh else self.store.getIdentityKeyPair()
registrationId = KeyHelper.generateRegistrationId() if fresh else self.store.getLocalRegistrationId()
preKeys = KeyHelper.generatePreKeys(KeyHelper.getRandomSequence(), countPreKeys)
signedPreKey = KeyHelper.generateSignedPreKey(identityKeyPair, KeyHelper.getRandomSequence(65536))
preKeysDict = {}
for preKey in preKeys:
keyPair = preKey.getKeyPair()
preKeysDict[self.adjustId(preKey.getId())] = self.adjustArray(keyPair.getPublicKey().serialize()[1:])
signedKeyTuple = (self.adjustId(signedPreKey.getId()),
self.adjustArray(signedPreKey.getKeyPair().getPublicKey().serialize()[1:]),
self.adjustArray(signedPreKey.getSignature()))
setKeysIq = SetKeysIqProtocolEntity(self.adjustArray(identityKeyPair.getPublicKey().serialize()[1:]), signedKeyTuple, preKeysDict, Curve.DJB_TYPE, self.adjustId(registrationId))
onResult = lambda _, __: self.persistKeys(registrationId, identityKeyPair, preKeys, signedPreKey, fresh)
self._sendIq(setKeysIq, onResult, self.onSentKeysError)
def persistKeys(self, registrationId, identityKeyPair, preKeys, signedPreKey, fresh):
total = len(preKeys)
curr = 0
prevPercentage = 0
if fresh:
self.store.storeLocalData(registrationId, identityKeyPair)
self.store.storeSignedPreKey(signedPreKey.getId(), signedPreKey)
for preKey in preKeys:
self.store.storePreKey(preKey.getId(), preKey)
curr += 1
currPercentage = int((curr * 100) / total)
if currPercentage == prevPercentage:
continue
prevPercentage = currPercentage
#logger.debug("%s" % currPercentage + "%")
sys.stdout.write("Storing prekeys %d%% \r" % (currPercentage))
sys.stdout.flush()
if fresh:
self.state = self.__class__._STATE_GENKEYS
self.broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT))
def onSentKeysError(self, errorNode, keysEntity):
raise Exception("Sent keys were not accepted")
def adjustArray(self, arr):
return HexUtil.decodeHex(binascii.hexlify(arr))
def adjustId(self, _id):
_id = format(_id, 'x')
zfiller = len(_id) if len(_id) % 2 == 0 else len(_id) + 1
_id = _id.zfill(zfiller if zfiller > 6 else 6)
# if len(_id) % 2:
# _id = "0" + _id
return binascii.unhexlify(_id)
yowsup-2.5.7/yowsup/layers/axolotl/layer_receive.py 0000664 0000000 0000000 00000032151 13221545743 0022622 0 ustar 00root root 0000000 0000000 from .layer_base import AxolotlBaseLayer
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.protocol_messages.proto.wa_pb2 import *
from yowsup.layers.axolotl.protocolentities import *
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.axolotl.props import PROP_IDENTITY_AUTOTRUST
from axolotl.protocol.prekeywhispermessage import PreKeyWhisperMessage
from axolotl.protocol.whispermessage import WhisperMessage
from axolotl.sessioncipher import SessionCipher
from axolotl.groups.groupcipher import GroupCipher
from axolotl.invalidmessageexception import InvalidMessageException
from axolotl.duplicatemessagexception import DuplicateMessageException
from axolotl.invalidkeyidexception import InvalidKeyIdException
from axolotl.nosessionexception import NoSessionException
from axolotl.untrustedidentityexception import UntrustedIdentityException
from axolotl.axolotladdress import AxolotlAddress
from axolotl.groups.senderkeyname import SenderKeyName
from axolotl.groups.groupsessionbuilder import GroupSessionBuilder
from axolotl.protocol.senderkeydistributionmessage import SenderKeyDistributionMessage
import logging
import copy
logger = logging.getLogger(__name__)
class AxolotlReceivelayer(AxolotlBaseLayer):
def __init__(self):
super(AxolotlReceivelayer, self).__init__()
self.v2Jids = [] #people we're going to send v2 enc messages
self.sessionCiphers = {}
self.groupCiphers = {}
self.pendingIncomingMessages = {} #(jid, participantJid?) => message
def receive(self, protocolTreeNode):
"""
:type protocolTreeNode: ProtocolTreeNode
"""
if not self.processIqRegistry(protocolTreeNode):
if protocolTreeNode.tag == "message":
self.onMessage(protocolTreeNode)
elif not protocolTreeNode.tag == "receipt":
#receipts will be handled by send layer
self.toUpper(protocolTreeNode)
# elif protocolTreeNode.tag == "iq":
# if protocolTreeNode.getChild("encr_media"):
# protocolTreeNode.addChild("media", {
# "url": protocolTreeNode["url"],
# "ip": protocolTreeNode["ip"],
# })
# self.toUpper(protocolTreeNode)
# return
######
def onEncrMediaResult(self, resultNode):
pass
def processPendingIncomingMessages(self, jid, participantJid = None):
conversationIdentifier = (jid, participantJid)
if conversationIdentifier in self.pendingIncomingMessages:
for messageNode in self.pendingIncomingMessages[conversationIdentifier]:
self.onMessage(messageNode)
del self.pendingIncomingMessages[conversationIdentifier]
##### handling received data #####
def onMessage(self, protocolTreeNode):
encNode = protocolTreeNode.getChild("enc")
if encNode:
self.handleEncMessage(protocolTreeNode)
else:
self.toUpper(protocolTreeNode)
def handleEncMessage(self, node):
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
isGroup = node["participant"] is not None
senderJid = node["participant"] if isGroup else node["from"]
if node.getChild("enc")["v"] == "2" and node["from"] not in self.v2Jids:
self.v2Jids.append(node["from"])
try:
if encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_PKMSG):
self.handlePreKeyWhisperMessage(node)
elif encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_MSG):
self.handleWhisperMessage(node)
if encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG):
self.handleSenderKeyMessage(node)
except (InvalidMessageException, InvalidKeyIdException) as e:
logger.warning("InvalidMessage or KeyId for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False))
retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode(node, self.store.getLocalRegistrationId())
self.toLower(retry.toProtocolTreeNode())
except NoSessionException as e:
logger.warning("No session for %s, getting their keys now", encMessageProtocolEntity.getAuthor(False))
conversationIdentifier = (node["from"], node["participant"])
if conversationIdentifier not in self.pendingIncomingMessages:
self.pendingIncomingMessages[conversationIdentifier] = []
self.pendingIncomingMessages[conversationIdentifier].append(node)
successFn = lambda successJids, b: self.processPendingIncomingMessages(*conversationIdentifier) if len(successJids) else None
self.getKeysFor([senderJid], successFn)
except DuplicateMessageException as e:
logger.warning("Received a message that we've previously decrypted, goint to send the delivery receipt myself")
self.toLower(OutgoingReceiptProtocolEntity(node["id"], node["from"], participant=node["participant"]).toProtocolTreeNode())
except UntrustedIdentityException as e:
if self.getProp(PROP_IDENTITY_AUTOTRUST, False):
logger.warning("Autotrusting identity for %s", e.getName())
self.store.saveIdentity(e.getName(), e.getIdentityKey())
return self.handleEncMessage(node)
else:
logger.error("Ignoring message with untrusted identity")
def handlePreKeyWhisperMessage(self, node):
pkMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
enc = pkMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_PKMSG)
preKeyWhisperMessage = PreKeyWhisperMessage(serialized=enc.getData())
sessionCipher = self.getSessionCipher(pkMessageProtocolEntity.getAuthor(False))
plaintext = sessionCipher.decryptPkmsg(preKeyWhisperMessage)
if enc.getVersion() == 2:
paddingByte = plaintext[-1] if type(plaintext[-1]) is int else ord(plaintext[-1])
padding = paddingByte & 0xFF
self.parseAndHandleMessageProto(pkMessageProtocolEntity, plaintext[:-padding])
else:
self.handleConversationMessage(node, plaintext)
def handleWhisperMessage(self, node):
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_MSG)
whisperMessage = WhisperMessage(serialized=enc.getData())
sessionCipher = self.getSessionCipher(encMessageProtocolEntity.getAuthor(False))
plaintext = sessionCipher.decryptMsg(whisperMessage)
if enc.getVersion() == 2:
paddingByte = plaintext[-1] if type(plaintext[-1]) is int else ord(plaintext[-1])
padding = paddingByte & 0xFF
self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext[:-padding])
else:
self.handleConversationMessage(encMessageProtocolEntity.toProtocolTreeNode(), plaintext)
def handleSenderKeyMessage(self, node):
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
enc = encMessageProtocolEntity.getEnc(EncProtocolEntity.TYPE_SKMSG)
senderKeyName = SenderKeyName(encMessageProtocolEntity.getFrom(True), AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0))
groupCipher = GroupCipher(self.store, senderKeyName)
try:
plaintext = groupCipher.decrypt(enc.getData())
padding = ord(plaintext[-1]) & 0xFF
plaintext = plaintext[:-padding]
plaintext = plaintext.encode() if sys.version_info >= (3, 0) else plaintext
self.parseAndHandleMessageProto(encMessageProtocolEntity, plaintext)
except NoSessionException as e:
logger.warning("No session for %s, going to send a retry", encMessageProtocolEntity.getAuthor(False))
retry = RetryOutgoingReceiptProtocolEntity.fromMessageNode(node, self.store.getLocalRegistrationId())
self.toLower(retry.toProtocolTreeNode())
def parseAndHandleMessageProto(self, encMessageProtocolEntity, serializedData):
node = encMessageProtocolEntity.toProtocolTreeNode()
m = Message()
handled = False
try:
m.ParseFromString(serializedData)
except:
print("DUMP:")
print(serializedData)
print([s for s in serializedData])
print([ord(s) for s in serializedData])
raise
if not m or not serializedData:
raise ValueError("Empty message")
if m.HasField("sender_key_distribution_message"):
handled = True
axolotlAddress = AxolotlAddress(encMessageProtocolEntity.getParticipant(False), 0)
self.handleSenderKeyDistributionMessage(m.sender_key_distribution_message, axolotlAddress)
if m.HasField("conversation"):
handled = True
self.handleConversationMessage(node, m.conversation)
elif m.HasField("contact_message"):
handled = True
self.handleContactMessage(node, m.contact_message)
elif m.HasField("url_message"):
handled = True
self.handleUrlMessage(node, m.url_message)
elif m.HasField("location_message"):
handled = True
self.handleLocationMessage(node, m.location_message)
elif m.HasField("image_message"):
handled = True
self.handleImageMessage(node, m.image_message)
if not handled:
print(m)
raise ValueError("Unhandled")
def handleSenderKeyDistributionMessage(self, senderKeyDistributionMessage, axolotlAddress):
groupId = senderKeyDistributionMessage.groupId
axolotlSenderKeyDistributionMessage = SenderKeyDistributionMessage(serialized=senderKeyDistributionMessage.axolotl_sender_key_distribution_message)
groupSessionBuilder = GroupSessionBuilder(self.store)
senderKeyName = SenderKeyName(groupId, axolotlAddress)
groupSessionBuilder.process(senderKeyName, axolotlSenderKeyDistributionMessage)
def handleConversationMessage(self, originalEncNode, text):
messageNode = copy.deepcopy(originalEncNode)
messageNode.children = []
messageNode.addChild(ProtocolTreeNode("body", data = text))
self.toUpper(messageNode)
def handleImageMessage(self, originalEncNode, imageMessage):
messageNode = copy.deepcopy(originalEncNode)
messageNode["type"] = "media"
mediaNode = ProtocolTreeNode("media", {
"type": "image",
"filehash": imageMessage.file_sha256,
"size": str(imageMessage.file_length),
"url": imageMessage.url,
"mimetype": imageMessage.mime_type,
"width": imageMessage.width,
"height": imageMessage.height,
"caption": imageMessage.caption,
"encoding": "raw",
"file": "enc",
"ip": "0"
}, data = imageMessage.jpeg_thumbnail)
messageNode.addChild(mediaNode)
self.toUpper(messageNode)
def handleUrlMessage(self, originalEncNode, urlMessage):
#convert to ??
pass
def handleDocumentMessage(self, originalEncNode, documentMessage):
#convert to ??
pass
def handleLocationMessage(self, originalEncNode, locationMessage):
messageNode = copy.deepcopy(originalEncNode)
messageNode["type"] = "media"
mediaNode = ProtocolTreeNode("media", {
"latitude": locationMessage.degrees_latitude,
"longitude": locationMessage.degress_longitude,
"name": "%s %s" % (locationMessage.name, locationMessage.address),
"url": locationMessage.url,
"encoding": "raw",
"type": "location"
}, data=locationMessage.jpeg_thumbnail)
messageNode.addChild(mediaNode)
self.toUpper(messageNode)
def handleContactMessage(self, originalEncNode, contactMessage):
messageNode = copy.deepcopy(originalEncNode)
messageNode["type"] = "media"
mediaNode = ProtocolTreeNode("media", {
"type": "vcard"
}, [
ProtocolTreeNode("vcard", {"name": contactMessage.display_name}, data = contactMessage.vcard)
] )
messageNode.addChild(mediaNode)
self.toUpper(messageNode)
def getSessionCipher(self, recipientId):
if recipientId in self.sessionCiphers:
sessionCipher = self.sessionCiphers[recipientId]
else:
sessionCipher = SessionCipher(self.store, self.store, self.store, self.store, recipientId, 1)
self.sessionCiphers[recipientId] = sessionCipher
return sessionCipher
def getGroupCipher(self, groupId, senderId):
senderKeyName = SenderKeyName(groupId, AxolotlAddress(senderId, 1))
if senderKeyName in self.groupCiphers:
groupCipher = self.groupCiphers[senderKeyName]
else:
groupCipher = GroupCipher(self.store, senderKeyName)
self.groupCiphers[senderKeyName] = groupCipher
return groupCipher
yowsup-2.5.7/yowsup/layers/axolotl/layer_send.py 0000664 0000000 0000000 00000035076 13221545743 0022142 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.proto.wa_pb2 import *
from yowsup.layers.protocol_messages.proto.wa_pb2 import SenderKeyDistributionMessage as ProtoSenderKeyDistributionMessage
from yowsup.layers.axolotl.protocolentities import *
from yowsup.layers.auth.layer_authentication import YowAuthenticationProtocolLayer
from yowsup.layers.protocol_groups.protocolentities import InfoGroupsIqProtocolEntity, InfoGroupsResultIqProtocolEntity
from axolotl.sessioncipher import SessionCipher
from axolotl.groups.groupcipher import GroupCipher
from axolotl.axolotladdress import AxolotlAddress
from axolotl.protocol.whispermessage import WhisperMessage
from axolotl.groups.senderkeyname import SenderKeyName
from axolotl.groups.groupsessionbuilder import GroupSessionBuilder
import logging
from random import randint
from .layer_base import AxolotlBaseLayer
logger = logging.getLogger(__name__)
class AxolotlSendLayer(AxolotlBaseLayer):
MAX_SENT_QUEUE = 100
def __init__(self):
super(AxolotlSendLayer, self).__init__()
self.sessionCiphers = {}
self.groupSessionBuilder = None
self.groupCiphers = {}
'''
Sent messages will be put in skalti entQueue until we receive a receipt for them.
This is for handling retry receipts which requires re-encrypting and resend of the original message
As the receipt for a sent message might arrive at a different yowsup instance,
ideally the original message should be fetched from a persistent storage.
Therefore, if the original message is not in sentQueue for any reason, we will
notify the upper layers and let them handle it.
'''
self.sentQueue = []
def onNewStoreSet(self, store):
if store is not None:
self.groupSessionBuilder = GroupSessionBuilder(store)
def __str__(self):
return "Axolotl Layer"
def send(self, node):
if node.tag == "message" and node["to"] not in self.skipEncJids and not node.getChild("enc") and (not node.getChild("media") or node.getChild("media")["mediakey"]):
self.processPlaintextNodeAndSend(node)
# elif node.tag == "iq" and node["xmlns"] == "w:m":
# mediaNode = node.getChild("media")
# if mediaNode and mediaNode["type"] == "image":
# iqNode = IqProtocolEntity.fromProtocolTreeNode(node).toProtocolTreeNode()
# iqNode.addChild(ProtocolTreeNode(
# "encr_media", {
# "type": mediaNode["type"],
# "hash": mediaNode["hash"]
# }
# ))
# self.toLower(iqNode)
else:
self.toLower(node)
def receive(self, protocolTreeNode):
if not self.processIqRegistry(protocolTreeNode):
if protocolTreeNode.tag == "receipt":
'''
Going to keep all group message enqueued, as we get receipts from each participant
So can't just remove it on first receipt. Therefore, the MAX queue length mechanism should better be working
'''
messageNode = self.getEnqueuedMessageNode(protocolTreeNode["id"], protocolTreeNode["participant"] is not None)
if not messageNode:
logger.debug("Axolotl layer does not have the message, bubbling it upwards")
self.toUpper(protocolTreeNode)
elif protocolTreeNode["type"] == "retry":
logger.info("Got retry to for message %s, and Axolotl layer has the message" % protocolTreeNode["id"])
retryReceiptEntity = RetryIncomingReceiptProtocolEntity.fromProtocolTreeNode(protocolTreeNode)
self.toLower(retryReceiptEntity.ack().toProtocolTreeNode())
self.getKeysFor(
[protocolTreeNode["participant"] or protocolTreeNode["from"]],
lambda successJids, b: self.processPlaintextNodeAndSend(messageNode, retryReceiptEntity) if len(successJids) == 1 else None
)
else:
#not interested in any non retry receipts, bubble upwards
self.toUpper(protocolTreeNode)
def processPlaintextNodeAndSend(self, node, retryReceiptEntity = None):
recipient_id = node["to"].split('@')[0]
isGroup = "-" in recipient_id
if node.getChild("media"):
self.toLower(node) # skip media enc for now, groups and non groups
elif isGroup:
self.sendToGroup(node, retryReceiptEntity)
elif self.store.containsSession(recipient_id, 1):
self.sendToContact(node)
else:
self.getKeysFor([node["to"]], lambda successJids, b: self.sendToContact(node) if len(successJids) == 1 else self.toLower(node), lambda: self.toLower(node))
def getPadding(self):
num = randint(1,255)
return bytearray([num] * num)
def groupSendSequence(self):
"""
check if senderkeyrecord exists
no: - create,
- get group jids from info request
- for each jid without a session, get keys to create the session
- send message with dist key for all participants
yes:
- send skmsg without any dist key
received retry for a participant
- request participants keys
- send message with dist key only + conversation, only for this participat
:return:
"""
def enqueueSent(self, node):
if len(self.sentQueue) >= self.__class__.MAX_SENT_QUEUE:
logger.warn("Discarding queued node without receipt")
self.sentQueue.pop(0)
self.sentQueue.append(node)
def getEnqueuedMessageNode(self, messageId, keepEnqueued = False):
for i in range(0, len(self.sentQueue)):
if self.sentQueue[i]["id"] == messageId:
if keepEnqueued:
return self.sentQueue[i]
return self.sentQueue.pop(i)
def sendEncEntities(self, node, encEntities):
mediaType = None
messageEntity = EncryptedMessageProtocolEntity(encEntities,
"text" if not mediaType else "media",
_id=node["id"],
to=node["to"],
notify=node["notify"],
timestamp=node["timestamp"],
participant=node["participant"],
offline=node["offline"],
retry=node["retry"]
)
self.enqueueSent(node)
self.toLower(messageEntity.toProtocolTreeNode())
def sendToContact(self, node):
recipient_id = node["to"].split('@')[0]
cipher = self.getSessionCipher(recipient_id)
messageData = self.serializeToProtobuf(node).SerializeToString() + self.getPadding()
ciphertext = cipher.encrypt(messageData)
mediaType = node.getChild("media")["type"] if node.getChild("media") else None
return self.sendEncEntities(node, [EncProtocolEntity(EncProtocolEntity.TYPE_MSG if ciphertext.__class__ == WhisperMessage else EncProtocolEntity.TYPE_PKMSG, 2, ciphertext.serialize(), mediaType)])
def sendToGroupWithSessions(self, node, jidsNeedSenderKey = None, retryCount=0):
jidsNeedSenderKey = jidsNeedSenderKey or []
groupJid = node["to"]
ownNumber = self.getLayerInterface(YowAuthenticationProtocolLayer).getUsername(False)
senderKeyName = SenderKeyName(groupJid, AxolotlAddress(ownNumber, 0))
cipher = self.getGroupCipher(groupJid, ownNumber)
encEntities = []
if len(jidsNeedSenderKey):
senderKeyDistributionMessage = self.groupSessionBuilder.create(senderKeyName)
for jid in jidsNeedSenderKey:
sessionCipher = self.getSessionCipher(jid.split('@')[0])
message = self.serializeSenderKeyDistributionMessageToProtobuf(node["to"], senderKeyDistributionMessage)
if retryCount > 0:
message = self.serializeToProtobuf(node, message)
ciphertext = sessionCipher.encrypt(message.SerializeToString() + self.getPadding())
encEntities.append(
EncProtocolEntity(
EncProtocolEntity.TYPE_MSG if ciphertext.__class__ == WhisperMessage else EncProtocolEntity.TYPE_PKMSG
, 2, ciphertext.serialize(), jid=jid
)
)
if not retryCount:
messageData = self.serializeToProtobuf(node).SerializeToString()
ciphertext = cipher.encrypt(messageData + self.getPadding())
mediaType = node.getChild("media")["type"] if node.getChild("media") else None
encEntities.append(EncProtocolEntity(EncProtocolEntity.TYPE_SKMSG, 2, ciphertext, mediaType))
self.sendEncEntities(node, encEntities)
def ensureSessionsAndSendToGroup(self, node, jids):
jidsNoSession = []
for jid in jids:
if not self.store.containsSession(jid.split('@')[0], 1):
jidsNoSession.append(jid)
if len(jidsNoSession):
self.getKeysFor(jidsNoSession, lambda successJids, b: self.sendToGroupWithSessions(node, successJids))
else:
self.sendToGroupWithSessions(node, jids)
def sendToGroup(self, node, retryReceiptEntity = None):
groupJid = node["to"]
ownNumber = self.getLayerInterface(YowAuthenticationProtocolLayer).getUsername(False)
ownJid = self.getLayerInterface(YowAuthenticationProtocolLayer).getUsername(True)
senderKeyName = SenderKeyName(node["to"], AxolotlAddress(ownNumber, 0))
senderKeyRecord = self.store.loadSenderKey(senderKeyName)
def sendToGroup(resultNode, requestEntity):
groupInfo = InfoGroupsResultIqProtocolEntity.fromProtocolTreeNode(resultNode)
jids = list(groupInfo.getParticipants().keys()) #keys in py3 returns dict_keys
if ownJid in jids:
jids.remove(ownJid)
return self.ensureSessionsAndSendToGroup(node, jids)
if senderKeyRecord.isEmpty():
groupInfoIq = InfoGroupsIqProtocolEntity(groupJid)
self._sendIq(groupInfoIq, sendToGroup)
else:
retryCount = 0
jidsNeedSenderKey = []
if retryReceiptEntity is not None:
retryCount = retryReceiptEntity.getRetryCount()
jidsNeedSenderKey.append(retryReceiptEntity.getRetryJid())
self.sendToGroupWithSessions(node, jidsNeedSenderKey, retryCount)
def serializeToProtobuf(self, node, message = None):
if node.getChild("body"):
return self.serializeTextToProtobuf(node, message)
elif node.getChild("media"):
return self.serializeMediaToProtobuf(node.getChild("media"), message)
else:
raise ValueError("No body or media nodes found")
def serializeTextToProtobuf(self, node, message = None):
m = message or Message()
m.conversation = node.getChild("body").getData()
return m
def serializeMediaToProtobuf(self, mediaNode, message = None):
if mediaNode["type"] == "image":
return self.serializeImageToProtobuf(mediaNode, message)
if mediaNode["type"] == "location":
return self.serializeLocationToProtobuf(mediaNode, message)
if mediaNode["type"] == "vcard":
return self.serializeContactToProtobuf(mediaNode, message)
return None
def serializeLocationToProtobuf(self, mediaNode, message = None):
m = message or Message()
location_message = LocationMessage()
location_message.degress_latitude = float(mediaNode["latitude"])
location_message.degress_longitude = float(mediaNode["longitude"])
location_message.address = mediaNode["name"]
location_message.name = mediaNode["name"]
location_message.url = mediaNode["url"]
m.location_message.MergeFrom(location_message)
return m
def serializeContactToProtobuf(self, mediaNode, message = None):
vcardNode = mediaNode.getChild("vcard")
m = message or Message()
contact_message = ContactMessage()
contact_message.display_name = vcardNode["name"]
m.vcard = vcardNode.getData()
m.contact_message.MergeFrom(contact_message)
return m
def serializeImageToProtobuf(self, mediaNode, message = None):
m = message or Message()
image_message = ImageMessage()
image_message.url = mediaNode["url"]
image_message.width = int(mediaNode["width"])
image_message.height = int(mediaNode["height"])
image_message.mime_type = mediaNode["mimetype"]
image_message.file_sha256 = mediaNode["filehash"]
image_message.file_length = int(mediaNode["size"])
image_message.caption = mediaNode["caption"] or ""
image_message.jpeg_thumbnail = mediaNode.getData()
m.image_message.MergeFrom(image_message)
return m
def serializeUrlToProtobuf(self, node, message = None):
pass
def serializeDocumentToProtobuf(self, node, message = None):
pass
def serializeSenderKeyDistributionMessageToProtobuf(self, groupId, senderKeyDistributionMessage, message = None):
m = message or Message()
sender_key_distribution_message = ProtoSenderKeyDistributionMessage()
sender_key_distribution_message.groupId = groupId
sender_key_distribution_message.axolotl_sender_key_distribution_message = senderKeyDistributionMessage.serialize()
m.sender_key_distribution_message.MergeFrom(sender_key_distribution_message)
# m.conversation = text
return m
###
def getSessionCipher(self, recipientId):
if recipientId in self.sessionCiphers:
sessionCipher = self.sessionCiphers[recipientId]
else:
sessionCipher = SessionCipher(self.store, self.store, self.store, self.store, recipientId, 1)
self.sessionCiphers[recipientId] = sessionCipher
return sessionCipher
def getGroupCipher(self, groupId, senderId):
senderKeyName = SenderKeyName(groupId, AxolotlAddress(senderId, 0))
if senderKeyName in self.groupCiphers:
groupCipher = self.groupCiphers[senderKeyName]
else:
groupCipher = GroupCipher(self.store, senderKeyName)
self.groupCiphers[senderKeyName] = groupCipher
return groupCipher
yowsup-2.5.7/yowsup/layers/axolotl/props.py 0000664 0000000 0000000 00000000125 13221545743 0021143 0 ustar 00root root 0000000 0000000 PROP_IDENTITY_AUTOTRUST = "org.openwhatsapp.yowsup.prop.axolotl.INDENTITY_AUTOTRUST" yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0023036 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/__init__.py 0000664 0000000 0000000 00000000704 13221545743 0025150 0 ustar 00root root 0000000 0000000 from .iq_key_get import GetKeysIqProtocolEntity
from .iq_keys_set import SetKeysIqProtocolEntity
from .iq_keys_get_result import ResultGetKeysIqProtocolEntity
from .message_encrypted import EncryptedMessageProtocolEntity
from .enc import EncProtocolEntity
from .notification_encrypt import EncryptNotification
from .receipt_outgoing_retry import RetryOutgoingReceiptProtocolEntity
from .receipt_incoming_retry import RetryIncomingReceiptProtocolEntity
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/enc.py 0000664 0000000 0000000 00000002610 13221545743 0024154 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
import sys
class EncProtocolEntity(ProtocolEntity):
TYPE_PKMSG = "pkmsg"
TYPE_MSG = "msg"
TYPE_SKMSG = "skmsg"
TYPES = (TYPE_PKMSG, TYPE_MSG, TYPE_SKMSG)
def __init__(self, type, version, data, mediaType = None, jid = None):
assert type in self.__class__.TYPES, "Unknown message enc type %s" % type
super(EncProtocolEntity, self).__init__("enc")
self.type = type
self.version = int(version)
self.data = data
self.mediaType = mediaType
self.jid = jid
def getType(self):
return self.type
def getVersion(self):
return self.version
def getData(self):
return self.data
def getMediaType(self):
return self.mediaType
def getJid(self):
return self.jid
def toProtocolTreeNode(self):
attribs = {"type": self.type, "v": str(self.version)}
if self.mediaType:
attribs["mediatype"] = self.mediaType
encNode = ProtocolTreeNode("enc", attribs, data = self.data)
if self.jid:
return ProtocolTreeNode("to", {"jid": self.jid}, [encNode])
return encNode
@staticmethod
def fromProtocolTreeNode(node):
return EncProtocolEntity(node["type"], node["v"], node.data.encode('latin-1') if sys.version_info >= (3,0) else node.data, node["mediatype"])
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/iq_key_get.py 0000664 0000000 0000000 00000001604 13221545743 0025531 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class GetKeysIqProtocolEntity(IqProtocolEntity):
def __init__(self, jids):
super(GetKeysIqProtocolEntity, self).__init__("encrypt", _type = "get", to = YowConstants.WHATSAPP_SERVER)
self.setJids(jids)
def setJids(self, jids):
assert type(jids) is list, "expected list of jids, got %s" % type(jids)
self.jids = jids
def getJids(self):
return self.jids
def toProtocolTreeNode(self):
node = super(GetKeysIqProtocolEntity, self).toProtocolTreeNode()
keyNode = ProtocolTreeNode("key")
for jid in self.getJids():
userNode = ProtocolTreeNode("user", { "jid": jid })
keyNode.addChild(userNode)
node.addChild(keyNode)
return node
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py 0000664 0000000 0000000 00000013077 13221545743 0027321 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
from axolotl.state.prekeybundle import PreKeyBundle
from axolotl.identitykey import IdentityKey
from axolotl.ecc.curve import Curve
from axolotl.ecc.djbec import DjbECPublicKey
import binascii
import sys
class ResultGetKeysIqProtocolEntity(ResultIqProtocolEntity):
"""
HEX:7a9cec4b
HEX:05
HEX:eeb668c8d062c99b43560c811acfe6e492798b496767eb060d99e011d3862369
HEX:000000
HEX:a1b5216ce4678143fb20aaaa2711a8c2b647230164b79414f0550b4e611ccd6c
HEX:94c231327fcd664b34603838b5e9ba926718d71c206e92b2b400f5cf4ae7bf17d83557bf328c1be6d51efdbd731a26d000adb8f38f140b1ea2a5fd3df2688085
HEX:36b545
HEX:c20826f622bec24b349ced38f1854bdec89ba098ef4c06b2402800d33e9aff61
"""
def __init__(self, _id, preKeyBundleMap = None):
super(ResultGetKeysIqProtocolEntity, self).__init__(_from = YowConstants.WHATSAPP_SERVER, _id=_id)
self.setPreKeyBundleMap(preKeyBundleMap)
def getJids(self):
return self.preKeyBundleMap.keys()
def setPreKeyBundleMap(self, preKeyBundleMap = None):
self.preKeyBundleMap = preKeyBundleMap or {}
def setPreKeyBundleFor(self, jid, preKeyBundle):
self.preKeyBundleMap[jid] = preKeyBundle
def getPreKeyBundleFor(self, jid):
if jid in self.preKeyBundleMap:
return self.preKeyBundleMap[jid]
@staticmethod
def _intToBytes(val):
return binascii.unhexlify(format(val, 'x').zfill(8).encode())
@staticmethod
def _bytesToInt(val):
if sys.version_info >= (3,0):
valEnc = val.encode('latin-1') if type(val) is str else val
else:
valEnc = val
return int(binascii.hexlify(valEnc), 16)
@staticmethod
def encStr(string):
if sys.version_info >= (3,0) and type(string) is str:
return string.encode('latin-1')
return string
@staticmethod
def fromProtocolTreeNode(node):
entity = ResultIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ResultGetKeysIqProtocolEntity
entity.setPreKeyBundleMap()
userNodes = node.getChild("list").getAllChildren()
for userNode in userNodes:
preKeyNode = userNode.getChild("key")
signedPreKeyNode = userNode.getChild("skey")
registrationId = ResultGetKeysIqProtocolEntity._bytesToInt(userNode.getChild("registration").getData())
identityKey = IdentityKey(DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(userNode.getChild("identity").getData())))
preKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(preKeyNode.getChild("id").getData())
preKeyPublic = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(preKeyNode.getChild("value").getData()))
signedPreKeyId = ResultGetKeysIqProtocolEntity._bytesToInt(signedPreKeyNode.getChild("id").getData())
signedPreKeySig = ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("signature").getData())
signedPreKeyPub = DjbECPublicKey(ResultGetKeysIqProtocolEntity.encStr(signedPreKeyNode.getChild("value").getData()))
preKeyBundle = PreKeyBundle(registrationId, 1, preKeyId, preKeyPublic,
signedPreKeyId, signedPreKeyPub, signedPreKeySig, identityKey)
entity.setPreKeyBundleFor(userNode["jid"], preKeyBundle)
return entity
def toProtocolTreeNode(self):
node = super(ResultGetKeysIqProtocolEntity, self).toProtocolTreeNode()
listNode = ProtocolTreeNode("list")
node.addChild(listNode)
for jid, preKeyBundle in self.preKeyBundleMap.items():
userNode = ProtocolTreeNode("user", {"jid": jid})
registrationNode = ProtocolTreeNode("registration", data = self.__class__._intToBytes(preKeyBundle.getRegistrationId()))
typeNode = ProtocolTreeNode("type", data = self.__class__._intToBytes(Curve.DJB_TYPE))
identityNode = ProtocolTreeNode("identity", data = preKeyBundle.getIdentityKey().getPublicKey().getPublicKey())
skeyNode = ProtocolTreeNode("skey")
skeyNode_idNode = ProtocolTreeNode("id", data=self.__class__._intToBytes(preKeyBundle.getSignedPreKeyId()))
skeyNode_valueNode = ProtocolTreeNode("value", data=preKeyBundle.getSignedPreKey().getPublicKey())
skeyNode_signatureNode = ProtocolTreeNode("signature", data=preKeyBundle.getSignedPreKeySignature())
skeyNode.addChildren([skeyNode_idNode, skeyNode_valueNode, skeyNode_signatureNode])
preKeyNode = ProtocolTreeNode("key")
preKeyNode_idNode = ProtocolTreeNode("id", data = self.__class__._intToBytes(preKeyBundle.getPreKeyId()))
preKeyNode_valueNode = ProtocolTreeNode("value", data= preKeyBundle.getPreKey().getPublicKey())
preKeyNode.addChildren([preKeyNode_idNode, preKeyNode_valueNode])
userNode.addChildren([
registrationNode,
typeNode,
identityNode,
skeyNode,
preKeyNode
])
listNode.addChild(userNode)
return node
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/iq_keys_set.py 0000664 0000000 0000000 00000005504 13221545743 0025733 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
import os, time
class SetKeysIqProtocolEntity(IqProtocolEntity):
def __init__(self, identityKey, signedPreKey, preKeys, djbType, registrationId = None):
super(SetKeysIqProtocolEntity, self).__init__("encrypt", _type = "set", to = YowConstants.WHATSAPP_SERVER)
self.setProps(identityKey, signedPreKey, preKeys, djbType, registrationId)
def setProps(self, identityKey, signedPreKey, preKeys, djbType, registrationId = None):
assert type(preKeys) is dict, "Expected keys to be a dict key_id -> public_key"
assert type(signedPreKey) is tuple, "Exception signed pre key to be tuple id,key,signature"
self.preKeys = preKeys
self.identityKey = identityKey
self.registration = registrationId or os.urandom(4)
self.djbType = int(djbType)
self.signedPreKey = signedPreKey
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SetKeysIqProtocolEntity
regVal = node.getChild("registration").data
typeVal = node.getChild("type").data
idVal = node.getChild("identity").data
preKeys = {}
for keyNode in node.getChild("list").getAllChildren():
preKeys[keyNode.getChild("id").data] = keyNode.getChild("value").data
skeyNode = node.getChild("skey")
entity.setProps(idVal, (skeyNode.getChild("id").data, skeyNode.getChild("value").data,
skeyNode.getChild("signature").data), preKeys, typeVal, regVal)
return entity
def toProtocolTreeNode(self):
node = super(SetKeysIqProtocolEntity, self).toProtocolTreeNode()
identityNode = ProtocolTreeNode("identity", data = self.identityKey)
listNode = ProtocolTreeNode("list")
keyNodes = []
for keyId, pk in self.preKeys.items():
keyNode = ProtocolTreeNode("key")
keyNode.addChild(ProtocolTreeNode("id", data = keyId))
keyNode.addChild(ProtocolTreeNode("value", data = pk))
keyNodes.append(keyNode)
listNode.addChildren(keyNodes)
regNode = ProtocolTreeNode("registration", data = self.registration)
typeNode = ProtocolTreeNode("type", data = chr(self.djbType))
_id, val, signature = self.signedPreKey
skeyNode = ProtocolTreeNode("skey", children = [
ProtocolTreeNode("id", data = _id),
ProtocolTreeNode("value", data = val),
ProtocolTreeNode("signature", data = signature)
])
node.addChildren([
listNode,
identityNode,
regNode,
typeNode,
skeyNode
])
return node
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/message_encrypted.py 0000664 0000000 0000000 00000004615 13221545743 0027117 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.protocolentities import MessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
import sys
from yowsup.layers.axolotl.protocolentities.enc import EncProtocolEntity
class EncryptedMessageProtocolEntity(MessageProtocolEntity):
'''
HEX:33089eb3c90312210510e0196be72fe65913c6a84e75a54f40a3ee290574d6a23f408df990e718da761a210521f1a3f3d5cb87fde19fadf618d3001b64941715efd3e0f36bba48c23b08c82f2242330a21059b0ce2c4720ec79719ba862ee3cda6d6332746d05689af13aabf43ea1c8d747f100018002210d31cd6ebea79e441c4935f72398c772e2ee21447eb675cfa28b99de8d2013000
'''
def __init__(self, encEntities, _type, _id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, offline = None, retry = None ):
super(EncryptedMessageProtocolEntity, self).__init__(_type, _id = _id, _from = _from, to = to, notify = notify,
timestamp = timestamp, participant = participant, offline = offline,
retry = retry)
self.setEncEntities(encEntities)
def setEncEntities(self, encEntities):
assert len(encEntities), "Must have at least 1 enc entity"
self.encEntities = encEntities
def getEnc(self, encType):
for enc in self.encEntities:
if enc.type == encType:
return enc
def toProtocolTreeNode(self):
node = super(EncryptedMessageProtocolEntity, self).toProtocolTreeNode()
participantsNode = ProtocolTreeNode("participants")
for enc in self.encEntities:
encNode = enc.toProtocolTreeNode()
if encNode.tag == "to":
participantsNode.addChild(encNode)
else:
node.addChild(encNode)
if len(participantsNode.getAllChildren()):
node.addChild(participantsNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = EncryptedMessageProtocolEntity
entity.setEncEntities([EncProtocolEntity.fromProtocolTreeNode(encNode) for encNode in node.getAllChildren("enc")])
return entity
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/notification_encrypt.py 0000664 0000000 0000000 00000002320 13221545743 0027637 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_notifications.protocolentities import NotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
class EncryptNotification(NotificationProtocolEntity):
"""
"""
def __init__(self, count, timestamp, _id = None, notify = None, offline = None):
super(EncryptNotification, self).__init__("encrypt", _id, YowConstants.WHATSAPP_SERVER, timestamp, notify, offline)
self.setProps(count)
def setProps(self, count):
self.count = int(count)
def getCount(self):
return self.count
def toProtocolTreeNode(self):
node = super(EncryptNotification, self).toProtocolTreeNode()
countNode = ProtocolTreeNode("count", {"value": str(self.count)})
node.addChild(countNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = NotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = EncryptNotification
entity.setProps(node.getChild("count")["value"])
return entity yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/receipt_incoming_retry.py 0000664 0000000 0000000 00000004561 13221545743 0030161 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_receipts.protocolentities import IncomingReceiptProtocolEntity
from yowsup.layers.axolotl.protocolentities.iq_keys_get_result import ResultGetKeysIqProtocolEntity
class RetryIncomingReceiptProtocolEntity(IncomingReceiptProtocolEntity):
'''
HEX:xxxxxxxxx
'''
def __init__(self, _id, jid, remoteRegistrationId, receiptTimestamp, retryTimestamp, v = 1, count = 1, participant = None, offline = None):
super(RetryIncomingReceiptProtocolEntity, self).__init__(_id, jid, receiptTimestamp, offline=offline, type="retry", participant=participant)
self.setRetryData(remoteRegistrationId, v,count, retryTimestamp)
def setRetryData(self, remoteRegistrationId, v, count, retryTimestamp):
self.remoteRegistrationId = remoteRegistrationId
self.v = int(v)
self.count = int(count)
self.retryTimestamp = int(retryTimestamp)
def toProtocolTreeNode(self):
node = super(RetryIncomingReceiptProtocolEntity, self).toProtocolTreeNode()
retry = ProtocolTreeNode("retry", {
"count": str(self.count),
"id": self.getId(),
"v": str(self.v),
"t": str(self.retryTimestamp)
})
node.addChild(retry)
registration = ProtocolTreeNode("registration", data=ResultGetKeysIqProtocolEntity._intToBytes(self.remoteRegistrationId))
node.addChild(registration)
return node
def getRetryCount(self):
return self.count
def getRetryJid(self):
return self.getParticipant() or self.getFrom()
def __str__(self):
out = super(RetryIncomingReceiptProtocolEntity, self).__str__()
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = IncomingReceiptProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = RetryIncomingReceiptProtocolEntity
retryNode = node.getChild("retry")
entity.setRetryData(ResultGetKeysIqProtocolEntity._bytesToInt(node.getChild("registration").data), retryNode["v"], retryNode["count"], retryNode["t"])
return entity
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/receipt_outgoing_retry.py 0000664 0000000 0000000 00000005431 13221545743 0030206 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.axolotl.protocolentities.iq_keys_get_result import ResultGetKeysIqProtocolEntity
class RetryOutgoingReceiptProtocolEntity(OutgoingReceiptProtocolEntity):
'''
HEX:xxxxxxxxx
'''
def __init__(self, _id, jid, localRegistrationId, retryTimestamp, v = 1, count = 1, participant = None):
super(RetryOutgoingReceiptProtocolEntity, self).__init__(_id, jid, participant=participant)
'''
Note to self: Android clients won't retry sending if the retry node didn't contain the message timestamp
'''
self.setRetryData(localRegistrationId, v,count, retryTimestamp)
def setRetryData(self, localRegistrationId, v, count, retryTimestamp):
self.localRegistrationId = localRegistrationId
self.v = v
self.count = count
self.retryTimestamp = int(retryTimestamp)
def toProtocolTreeNode(self):
node = super(RetryOutgoingReceiptProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("type", "retry")
retryAttribs = {
"count": str(self.count),
"id":self.getId(),
"v":str(self.v),
"t": str(self.retryTimestamp)
}
retry = ProtocolTreeNode("retry", retryAttribs)
node.addChild(retry)
registration = ProtocolTreeNode("registration", data=ResultGetKeysIqProtocolEntity._intToBytes(self.localRegistrationId))
node.addChild(registration)
return node
def __str__(self):
out = super(RetryOutgoingReceiptProtocolEntity, self).__str__()
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = OutgoingReceiptProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = RetryOutgoingReceiptProtocolEntity
retryNode = node.getChild("retry")
entity.setRetryData(ResultGetKeysIqProtocolEntity._bytesToInt(node.getChild("registration").data), retryNode["v"], retryNode["count"], retryNode["t"])
return entity
@staticmethod
def fromMessageNode(messageNodeToBeRetried, localRegistrationId):
return RetryOutgoingReceiptProtocolEntity(
messageNodeToBeRetried.getAttributeValue("id"),
messageNodeToBeRetried.getAttributeValue("from"),
localRegistrationId,
messageNodeToBeRetried.getAttributeValue("t"),
participant=messageNodeToBeRetried.getAttributeValue("participant")
)
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/test_iq_keys_get_result.py 0000664 0000000 0000000 00000005444 13221545743 0030357 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities.test_iq_result import ResultIqProtocolEntityTest
from yowsup.layers.axolotl.protocolentities import ResultGetKeysIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
from axolotl.util.keyhelper import KeyHelper
from axolotl.ecc.curve import Curve
class ResultGetKeysIqProtocolEntityTest(ResultIqProtocolEntityTest):
def setUp(self):
super(ResultIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = ResultGetKeysIqProtocolEntity
listNode = ProtocolTreeNode("list")
self.node.addChild(listNode)
for i in range(0, 1):
userNode = ProtocolTreeNode("user", {"jid": "user_%s@%s" % (i, YowConstants.WHATSAPP_SERVER)})
listNode.addChild(userNode)
registrationNode = ProtocolTreeNode("registration",
data = ResultGetKeysIqProtocolEntity._intToBytes(
KeyHelper.generateRegistrationId()))
typeNode = ProtocolTreeNode("type", data = ResultGetKeysIqProtocolEntity._intToBytes(Curve.DJB_TYPE))
identityKeyPair = KeyHelper.generateIdentityKeyPair()
identityNode = ProtocolTreeNode("identity", data=identityKeyPair.getPublicKey().getPublicKey().getPublicKey())
signedPreKey = KeyHelper.generateSignedPreKey(identityKeyPair, i)
signedPreKeyNode = ProtocolTreeNode("skey")
signedPreKeyNode_idNode = ProtocolTreeNode("id",
data = ResultGetKeysIqProtocolEntity._intToBytes(
signedPreKey.getId()))
signedPreKeyNode_valueNode = ProtocolTreeNode("value",
data = signedPreKey.getKeyPair().getPublicKey().getPublicKey())
signedPreKeyNode_sigNode = ProtocolTreeNode("signature",
data = signedPreKey.getSignature())
signedPreKeyNode.addChildren([signedPreKeyNode_idNode, signedPreKeyNode_valueNode, signedPreKeyNode_sigNode])
preKey = KeyHelper.generatePreKeys(i * 10, 1)[0]
preKeyNode = ProtocolTreeNode("key")
preKeyNode_idNode = ProtocolTreeNode("id", data = ResultGetKeysIqProtocolEntity._intToBytes(preKey.getId()))
preKeyNode_valNode = ProtocolTreeNode("value", data = preKey.getKeyPair().getPublicKey().getPublicKey())
preKeyNode.addChildren([preKeyNode_idNode, preKeyNode_valNode])
userNode.addChildren([
registrationNode,
typeNode,
identityNode,
signedPreKeyNode,
preKeyNode
])
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/test_iq_keys_set.py 0000664 0000000 0000000 00000001747 13221545743 0026777 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.axolotl.protocolentities import SetKeysIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class SetKeysIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(SetKeysIqProtocolEntityTest, self).setUp()
# self.ProtocolEntity = SetKeysIqProtocolEntity
#
# regNode = ProtocolTreeNode("registration", data = "abcd")
# idNode = ProtocolTreeNode("identity", data = "efgh")
# typeNode = ProtocolTreeNode("type", data = "ijkl")
# listNode = ProtocolTreeNode("list")
# for i in range(0, 2):
# keyNode = ProtocolTreeNode("key", children=[
# ProtocolTreeNode("id", data = "id_%s" % i),
# ProtocolTreeNode("value", data = "val_%s" % i)
# ])
# listNode.addChild(keyNode)
#
# self.node.addChildren([regNode, idNode, typeNode, listNode])
yowsup-2.5.7/yowsup/layers/axolotl/protocolentities/test_notification_encrypt.py 0000664 0000000 0000000 00000000746 13221545743 0030710 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_notifications.protocolentities.test_notification import NotificationProtocolEntityTest
from yowsup.layers.axolotl.protocolentities import EncryptNotification
from yowsup.structs import ProtocolTreeNode
class TestEncryptNotification(NotificationProtocolEntityTest):
def setUp(self):
super(TestEncryptNotification, self).setUp()
self.ProtocolEntity = EncryptNotification
self.node.addChild(ProtocolTreeNode("count", {"value": "9"})) yowsup-2.5.7/yowsup/layers/axolotl/store/ 0000775 0000000 0000000 00000000000 13221545743 0020564 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/axolotl/store/__init__.py 0000664 0000000 0000000 00000000000 13221545743 0022663 0 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/ 0000775 0000000 0000000 00000000000 13221545743 0022065 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/__init__.py 0000664 0000000 0000000 00000000025 13221545743 0024173 0 ustar 00root root 0000000 0000000 __author__ = 'tarek'
yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/liteaxolotlstore.py 0000664 0000000 0000000 00000006526 13221545743 0026065 0 ustar 00root root 0000000 0000000 from axolotl.state.axolotlstore import AxolotlStore
from .liteidentitykeystore import LiteIdentityKeyStore
from .liteprekeystore import LitePreKeyStore
from .litesessionstore import LiteSessionStore
from .litesignedprekeystore import LiteSignedPreKeyStore
from .litesenderkeystore import LiteSenderKeyStore
import sqlite3
class LiteAxolotlStore(AxolotlStore):
def __init__(self, db):
conn = sqlite3.connect(db, check_same_thread=False)
conn.text_factory = bytes
self.identityKeyStore = LiteIdentityKeyStore(conn)
self.preKeyStore = LitePreKeyStore(conn)
self.signedPreKeyStore = LiteSignedPreKeyStore(conn)
self.sessionStore = LiteSessionStore(conn)
self.senderKeyStore = LiteSenderKeyStore(conn)
def getIdentityKeyPair(self):
return self.identityKeyStore.getIdentityKeyPair()
def storeLocalData(self, registrationId, identityKeyPair):
self.identityKeyStore.storeLocalData(registrationId, identityKeyPair)
def getLocalRegistrationId(self):
return self.identityKeyStore.getLocalRegistrationId()
def saveIdentity(self, recepientId, identityKey):
self.identityKeyStore.saveIdentity(recepientId, identityKey)
def isTrustedIdentity(self, recepientId, identityKey):
return self.identityKeyStore.isTrustedIdentity(recepientId, identityKey)
def loadPreKey(self, preKeyId):
return self.preKeyStore.loadPreKey(preKeyId)
def loadPreKeys(self):
return self.preKeyStore.loadPendingPreKeys()
def storePreKey(self, preKeyId, preKeyRecord):
self.preKeyStore.storePreKey(preKeyId, preKeyRecord)
def containsPreKey(self, preKeyId):
return self.preKeyStore.containsPreKey(preKeyId)
def removePreKey(self, preKeyId):
self.preKeyStore.removePreKey(preKeyId)
def loadSession(self, recepientId, deviceId):
return self.sessionStore.loadSession(recepientId, deviceId)
def getSubDeviceSessions(self, recepientId):
return self.sessionStore.getSubDeviceSessions(recepientId)
def storeSession(self, recepientId, deviceId, sessionRecord):
self.sessionStore.storeSession(recepientId, deviceId, sessionRecord)
def containsSession(self, recepientId, deviceId):
return self.sessionStore.containsSession(recepientId, deviceId)
def deleteSession(self, recepientId, deviceId):
self.sessionStore.deleteSession(recepientId, deviceId)
def deleteAllSessions(self, recepientId):
self.sessionStore.deleteAllSessions(recepientId)
def loadSignedPreKey(self, signedPreKeyId):
return self.signedPreKeyStore.loadSignedPreKey(signedPreKeyId)
def loadSignedPreKeys(self):
return self.signedPreKeyStore.loadSignedPreKeys()
def storeSignedPreKey(self, signedPreKeyId, signedPreKeyRecord):
self.signedPreKeyStore.storeSignedPreKey(signedPreKeyId, signedPreKeyRecord)
def containsSignedPreKey(self, signedPreKeyId):
return self.signedPreKeyStore.containsSignedPreKey(signedPreKeyId)
def removeSignedPreKey(self, signedPreKeyId):
self.signedPreKeyStore.removeSignedPreKey(signedPreKeyId)
def loadSenderKey(self, senderKeyName):
return self.senderKeyStore.loadSenderKey(senderKeyName)
def storeSenderKey(self, senderKeyName, senderKeyRecord):
self.senderKeyStore.storeSenderKey(senderKeyName, senderKeyRecord)
yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/liteidentitykeystore.py 0000664 0000000 0000000 00000006040 13221545743 0026734 0 ustar 00root root 0000000 0000000 from axolotl.state.identitykeystore import IdentityKeyStore
from axolotl.identitykey import IdentityKey
from axolotl.identitykeypair import IdentityKeyPair
from axolotl.ecc.djbec import *
import sys
class LiteIdentityKeyStore(IdentityKeyStore):
def __init__(self, dbConn):
"""
:type dbConn: Connection
"""
self.dbConn = dbConn
dbConn.execute("CREATE TABLE IF NOT EXISTS identities (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"recipient_id INTEGER UNIQUE,"
"registration_id INTEGER, public_key BLOB, private_key BLOB,"
"next_prekey_id INTEGER, timestamp INTEGER);")
#identityKeyPairKeys = Curve.generateKeyPair()
#self.identityKeyPair = IdentityKeyPair(IdentityKey(identityKeyPairKeys.getPublicKey()),
# identityKeyPairKeys.getPrivateKey())
# self.localRegistrationId = KeyHelper.generateRegistrationId()
def getIdentityKeyPair(self):
q = "SELECT public_key, private_key FROM identities WHERE recipient_id = -1"
c = self.dbConn.cursor()
c.execute(q)
result = c.fetchone()
publicKey, privateKey = result
return IdentityKeyPair(IdentityKey(DjbECPublicKey(publicKey[1:])), DjbECPrivateKey(privateKey))
def getLocalRegistrationId(self):
q = "SELECT registration_id FROM identities WHERE recipient_id = -1"
c = self.dbConn.cursor()
c.execute(q)
result = c.fetchone()
return result[0] if result else None
def storeLocalData(self, registrationId, identityKeyPair):
q = "INSERT INTO identities(recipient_id, registration_id, public_key, private_key) VALUES(-1, ?, ?, ?)"
c = self.dbConn.cursor()
pubKey = identityKeyPair.getPublicKey().getPublicKey().serialize()
privKey = identityKeyPair.getPrivateKey().serialize()
if sys.version_info < (2,7):
pubKey = buffer(pubKey)
privKey = buffer(privKey)
c.execute(q, (registrationId,
pubKey,
privKey))
self.dbConn.commit()
def saveIdentity(self, recipientId, identityKey):
q = "DELETE FROM identities WHERE recipient_id=?"
self.dbConn.cursor().execute(q, (recipientId,))
self.dbConn.commit()
q = "INSERT INTO identities (recipient_id, public_key) VALUES(?, ?)"
c = self.dbConn.cursor()
pubKey = identityKey.getPublicKey().serialize()
c.execute(q, (recipientId, buffer(pubKey) if sys.version_info < (2,7) else pubKey))
self.dbConn.commit()
def isTrustedIdentity(self, recipientId, identityKey):
q = "SELECT public_key from identities WHERE recipient_id = ?"
c = self.dbConn.cursor()
c.execute(q, (recipientId,))
result = c.fetchone()
if not result:
return True
pubKey = identityKey.getPublicKey().serialize()
if sys.version_info < (2, 7):
pubKey = buffer(pubKey)
return result[0] == pubKey yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/liteprekeystore.py 0000664 0000000 0000000 00000003460 13221545743 0025674 0 ustar 00root root 0000000 0000000 from axolotl.state.prekeystore import PreKeyStore
from axolotl.state.prekeyrecord import PreKeyRecord
import sys
class LitePreKeyStore(PreKeyStore):
def __init__(self, dbConn):
"""
:type dbConn: Connection
"""
self.dbConn = dbConn
dbConn.execute("CREATE TABLE IF NOT EXISTS prekeys (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"prekey_id INTEGER UNIQUE, sent_to_server BOOLEAN, record BLOB);")
def loadPreKey(self, preKeyId):
q = "SELECT record FROM prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (preKeyId,))
result = cursor.fetchone()
if not result:
raise Exception("No such prekeyRecord!")
return PreKeyRecord(serialized = result[0])
def loadPendingPreKeys(self):
q = "SELECT record FROM prekeys"
cursor = self.dbConn.cursor()
cursor.execute(q)
result = cursor.fetchall()
return [PreKeyRecord(serialized=result[0]) for result in result]
def storePreKey(self, preKeyId, preKeyRecord):
#self.removePreKey(preKeyId)
q = "INSERT INTO prekeys (prekey_id, record) VALUES(?,?)"
cursor = self.dbConn.cursor()
serialized = preKeyRecord.serialize()
cursor.execute(q, (preKeyId, buffer(serialized) if sys.version_info < (2,7) else serialized))
self.dbConn.commit()
def containsPreKey(self, preKeyId):
q = "SELECT record FROM prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (preKeyId,))
return cursor.fetchone() is not None
def removePreKey(self, preKeyId):
q = "DELETE FROM prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (preKeyId,))
self.dbConn.commit()
yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/litesenderkeystore.py 0000664 0000000 0000000 00000003751 13221545743 0026371 0 ustar 00root root 0000000 0000000 from axolotl.groups.state.senderkeystore import SenderKeyStore
from axolotl.groups.state.senderkeyrecord import SenderKeyRecord
import sqlite3
import sys
class LiteSenderKeyStore(SenderKeyStore):
def __init__(self, dbConn):
"""
:type dbConn: Connection
"""
self.dbConn = dbConn
dbConn.execute("CREATE TABLE IF NOT EXISTS sender_keys (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"group_id TEXT NOT NULL,"
"sender_id INTEGER NOT NULL, record BLOB);")
dbConn.execute("CREATE UNIQUE INDEX IF NOT EXISTS sender_keys_idx ON sender_keys (group_id, sender_id);")
def storeSenderKey(self, senderKeyName, senderKeyRecord):
"""
:type senderKeyName: SenderKeName
:type senderKeyRecord: SenderKeyRecord
"""
q = "INSERT INTO sender_keys (group_id, sender_id, record) VALUES(?,?, ?)"
cursor = self.dbConn.cursor()
serialized = senderKeyRecord.serialize()
if sys.version_info < (2,7):
serialized = buffer(serialized)
try:
cursor.execute(q, (senderKeyName.getGroupId(), senderKeyName.getSender().getName(), serialized))
self.dbConn.commit()
except sqlite3.IntegrityError as e:
q = "UPDATE sender_keys set record = ? WHERE group_id = ? and sender_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (serialized, senderKeyName.getGroupId(), senderKeyName.getSender().getName()))
self.dbConn.commit()
def loadSenderKey(self, senderKeyName):
"""
:type senderKeyName: SenderKeyName
"""
q = "SELECT record FROM sender_keys WHERE group_id = ? and sender_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (senderKeyName.getGroupId(), senderKeyName.getSender().getName()))
result = cursor.fetchone()
if not result:
return SenderKeyRecord()
return SenderKeyRecord(serialized = result[0])
yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/litesessionstore.py 0000664 0000000 0000000 00000004312 13221545743 0026055 0 ustar 00root root 0000000 0000000 from axolotl.state.sessionstore import SessionStore
from axolotl.state.sessionrecord import SessionRecord
import sys
class LiteSessionStore(SessionStore):
def __init__(self, dbConn):
"""
:type dbConn: Connection
"""
self.dbConn = dbConn
dbConn.execute("CREATE TABLE IF NOT EXISTS sessions (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"recipient_id INTEGER UNIQUE, device_id INTEGER, record BLOB, timestamp INTEGER);")
def loadSession(self, recipientId, deviceId):
q = "SELECT record FROM sessions WHERE recipient_id = ? AND device_id = ?"
c = self.dbConn.cursor()
c.execute(q, (recipientId, deviceId))
result = c.fetchone()
if result:
return SessionRecord(serialized=result[0])
else:
return SessionRecord()
def getSubDeviceSessions(self, recipientId):
q = "SELECT device_id from sessions WHERE recipient_id = ?"
c = self.dbConn.cursor()
c.execute(q, (recipientId,))
result = c.fetchall()
deviceIds = [r[0] for r in result]
return deviceIds
def storeSession(self, recipientId, deviceId, sessionRecord):
self.deleteSession(recipientId, deviceId)
q = "INSERT INTO sessions(recipient_id, device_id, record) VALUES(?,?,?)"
c = self.dbConn.cursor()
serialized = sessionRecord.serialize()
c.execute(q, (recipientId, deviceId, buffer(serialized) if sys.version_info < (2,7) else serialized))
self.dbConn.commit()
def containsSession(self, recipientId, deviceId):
q = "SELECT record FROM sessions WHERE recipient_id = ? AND device_id = ?"
c = self.dbConn.cursor()
c.execute(q, (recipientId, deviceId))
result = c.fetchone()
return result is not None
def deleteSession(self, recipientId, deviceId):
q = "DELETE FROM sessions WHERE recipient_id = ? AND device_id = ?"
self.dbConn.cursor().execute(q, (recipientId, deviceId))
self.dbConn.commit()
def deleteAllSessions(self, recipientId):
q = "DELETE FROM sessions WHERE recipient_id = ?"
self.dbConn.cursor().execute(q, (recipientId,))
self.dbConn.commit()
yowsup-2.5.7/yowsup/layers/axolotl/store/sqlite/litesignedprekeystore.py 0000664 0000000 0000000 00000004342 13221545743 0027066 0 ustar 00root root 0000000 0000000 from axolotl.state.signedprekeystore import SignedPreKeyStore
from axolotl.state.signedprekeyrecord import SignedPreKeyRecord
from axolotl.invalidkeyidexception import InvalidKeyIdException
import sys
class LiteSignedPreKeyStore(SignedPreKeyStore):
def __init__(self, dbConn):
"""
:type dbConn: Connection
"""
self.dbConn = dbConn
dbConn.execute("CREATE TABLE IF NOT EXISTS signed_prekeys (_id INTEGER PRIMARY KEY AUTOINCREMENT,"
"prekey_id INTEGER UNIQUE, timestamp INTEGER, record BLOB);")
def loadSignedPreKey(self, signedPreKeyId):
q = "SELECT record FROM signed_prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (signedPreKeyId,))
result = cursor.fetchone()
if not result:
raise InvalidKeyIdException("No such signedprekeyrecord! %s " % signedPreKeyId)
return SignedPreKeyRecord(serialized=result[0])
def loadSignedPreKeys(self):
q = "SELECT record FROM signed_prekeys"
cursor = self.dbConn.cursor()
cursor.execute(q,)
result = cursor.fetchall()
results = []
for row in result:
results.append(SignedPreKeyRecord(serialized=row[0]))
return results
def storeSignedPreKey(self, signedPreKeyId, signedPreKeyRecord):
#q = "DELETE FROM signed_prekeys WHERE prekey_id = ?"
#self.dbConn.cursor().execute(q, (signedPreKeyId,))
#self.dbConn.commit()
q = "INSERT INTO signed_prekeys (prekey_id, record) VALUES(?,?)"
cursor = self.dbConn.cursor()
record = signedPreKeyRecord.serialize()
cursor.execute(q, (signedPreKeyId, buffer(record) if sys.version_info < (2,7) else record))
self.dbConn.commit()
def containsSignedPreKey(self, signedPreKeyId):
q = "SELECT record FROM signed_prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (signedPreKeyId,))
return cursor.fetchone() is not None
def removeSignedPreKey(self, signedPreKeyId):
q = "DELETE FROM signed_prekeys WHERE prekey_id = ?"
cursor = self.dbConn.cursor()
cursor.execute(q, (signedPreKeyId,))
self.dbConn.commit()
yowsup-2.5.7/yowsup/layers/coder/ 0000775 0000000 0000000 00000000000 13221545743 0017042 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/coder/__init__.py 0000664 0000000 0000000 00000000040 13221545743 0021145 0 ustar 00root root 0000000 0000000 from .layer import YowCoderLayer yowsup-2.5.7/yowsup/layers/coder/decoder.py 0000664 0000000 0000000 00000021032 13221545743 0021017 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
import math
import binascii
import sys
class ReadDecoder:
def __init__(self, tokenDictionary):
self.streamStarted = False;
self.tokenDictionary = tokenDictionary
def reset(self):
self.streamStarted = False
def getProtocolTreeNode(self, data):
if not self.streamStarted:
return self.streamStart(data)
return self.nextTreeInternal(data)
def getToken(self, index, data):
token = self.tokenDictionary.getToken(index)
if not token:
index = self.readInt8(data)
token = self.tokenDictionary.getToken(index, True)
if not token:
raise ValueError("Invalid token %s" % token)
return token
def getTokenDouble(self, n, n2):
pos = n2 + n * 256
token = self.tokenDictionary.getToken(pos, True)
if not token:
raise ValueError("Invalid token %s" % pos)
return token
def streamStart(self, data):
self.streamStarted = True
tag = data.pop(0)
size = self.readListSize(tag, data)
tag = data.pop(0)
if tag != 1:
if tag == 236:
tag = data.pop(0) + 237
token = self.getToken(tag, data)#self.tokenDictionary.getToken(tag)
raise Exception("expecting STREAM_START in streamStart, instead got token: %s" % token)
attribCount = (size - 2 + size % 2) / 2
self.readAttributes(attribCount, data)
def readNibble(self, data):
_byte = self.readInt8(data)
ignoreLastNibble = bool(_byte & 0x80)
size = (_byte & 0x7f)
nrOfNibbles = size * 2 - int(ignoreLastNibble)
dataArr = self.readArray(size, data)
string = ''
for i in range(0, nrOfNibbles):
_byte = dataArr[int(math.floor(i/2))]
_shift = 4 * (1 - i % 2)
dec = (_byte & (15 << _shift)) >> _shift
if dec in (0,1,2,3,4,5,6,7,8,9):
string += str(dec)
elif dec in (10, 11):
string += chr(dec - 10 + 45)
else:
raise Exception("Bad nibble %s" % dec)
return string
def readPacked8(self, n, data):
size = self.readInt8(data)
remove = 0
if (size & 0x80) != 0 and n == 251:
remove = 1
size = size & 0x7F
text = bytearray(self.readArray(size, data))
hexData = binascii.hexlify(str(text) if sys.version_info < (2,7) else text).upper()
dataSize = len(hexData)
out = []
if remove == 0:
for i in range(0, dataSize):
char = chr(hexData[i]) if type(hexData[i]) is int else hexData[i] #python2/3 compat
val = ord(binascii.unhexlify("0%s" % char))
if i == (dataSize - 1) and val > 11 and n != 251: continue
out.append(self.unpackByte(n, val))
else:
out = map(ord, list(hexData[0: -remove])) if sys.version_info < (3,0) else list(hexData[0: -remove])
return out
def unpackByte(self, n, n2):
if n == 251:
return self.unpackHex(n2)
if n == 255:
return self.unpackNibble(n2)
raise ValueError("bad packed type %s" % n)
def unpackHex(self, n):
if n in range(0, 10):
return n + 48
if n in range(10, 16):
return 65 + (n - 10)
raise ValueError("bad hex %s" % n)
def unpackNibble(self, n):
if n in range(0, 10):
return n + 48
if n in (10, 11):
return 45 + (n - 10)
raise ValueError("bad nibble %s" % n)
def readHeader(self, data, offset = 0):
ret = 0
if len(data) >= (3 + offset):
b0 = data[offset]
b1 = data[offset + 1]
b2 = data[offset + 2]
ret = b0 + (b1 << 16) + (b2 << 8)
return ret
def readInt8(self, data):
return data.pop(0);
def readInt16(self, data):
intTop = data.pop(0)
intBot = data.pop(0)
value = (intTop << 8) + intBot
if value is not None:
return value
else:
return ""
def readInt20(self, data):
int1 = data.pop(0)
int2 = data.pop(0)
int3 = data.pop(0)
return ((int1 & 0xF) << 16) | (int2 << 8) | int3
def readInt24(self, data):
int1 = data.pop(0)
int2 = data.pop(0)
int3 = data.pop(0)
value = (int1 << 16) + (int2 << 8) + (int3 << 0)
return value
def readInt31(self, data):
data.pop(0)
int1 = data.pop(0)
int2 = data.pop(0)
int3 = data.pop(0)
return (int1 << 24) | (int1 << 16) | int2 << 8 | int3
def readListSize(self,token, data):
size = 0
if token == 0:
size = 0
else:
if token == 248:
size = self.readInt8(data)
else:
if token == 249:
size = self.readInt16(data)
else:
raise Exception("invalid list size in readListSize: token " + str(token))
return size
def readAttributes(self, attribCount, data):
attribs = {}
for i in range(0, int(attribCount)):
key = self.readString(self.readInt8(data), data)
value = self.readString(self.readInt8(data), data)
attribs[key]=value
return attribs
def readString(self,token, data):
if token == -1:
raise Exception("-1 token in readString")
if 2 < token < 236:
return self.getToken(token, data)
if token == 0:
return None
if token in (236, 237, 238, 239):
return self.getTokenDouble(token - 236, self.readInt8(data))
if token == 250:
user = self.readString(data.pop(0), data)
server = self.readString(data.pop(0), data)
if user is not None and server is not None:
return user + "@" + server
if server is not None:
return server
raise Exception("readString couldn't reconstruct jid")
if token in (251, 255):
return "".join(map(chr, self.readPacked8(token, data)))
if token == 252:
size8 = self.readInt8(data)
buf8 = self.readArray(size8, data)
return "".join(map(chr, buf8))
if token == 253:
size20 = self.readInt20(data)
buf20 = self.readArray(size20, data)
return "".join(map(chr, buf20))
if token == 254:
size31 = self.readInt31()
buf31 = self.readArray(size31, data)
return "".join(map(chr, buf31))
raise Exception("readString couldn't match token "+str(token))
def readArray(self, length, data):
out = []
for i in range(0, length):
out.append(data.pop(0))
return out
def nextTreeInternal(self, data):
size = self.readListSize(self.readInt8(data), data)
token = self.readInt8(data)
if token == 1:
token = self.readInt8(data)
if token == 2:
return None
tag = self.readString(token, data)
if size == 0 or tag is None:
raise ValueError("nextTree sees 0 list or null tag")
attribCount = (size - 2 + size % 2)/2
attribs = self.readAttributes(attribCount, data)
if size % 2 ==1:
return ProtocolTreeNode(tag, attribs)
read2 = self.readInt8(data)
nodeData = None
nodeChildren = None
if self.isListTag(read2):
nodeChildren = self.readList(read2, data)
elif read2 == 252:
size = self.readInt8(data)
nodeData = self.readArray(size, data)
elif read2 == 253:
size = self.readInt20(data)
nodeData = self.readArray(size, data)
elif read2 == 254:
size = self.readInt31(data)
nodeData = self.readArray(size, data)
elif read2 in (255, 251):
nodeData = self.readPacked8(read2, data)
else:
nodeData = self.readString(read2, data)
if nodeData and type(nodeData) is not str:
nodeData = "".join(map(chr, nodeData))
return ProtocolTreeNode(tag, attribs, nodeChildren, nodeData)
def readList(self,token, data):
size = self.readListSize(token, data)
listx = []
for i in range(0,size):
listx.append(self.nextTreeInternal(data))
return listx;
def isListTag(self, b):
return b in (248, 0, 249)
yowsup-2.5.7/yowsup/layers/coder/encoder.py 0000664 0000000 0000000 00000013646 13221545743 0021045 0 ustar 00root root 0000000 0000000 class WriteEncoder:
def __init__(self, tokenDictionary):
self.tokenDictionary = tokenDictionary
self.streamStarted = False
def reset(self):
self.streamStarted = False
def getStreamStartBytes(self, domain, resource):
data = []
self.streamStarted = True
data.append(87)
data.append(65)
data.append(1)
data.append(6)
streamOpenAttributes = {"to": domain, "resource": resource}
self.writeListStart(len(streamOpenAttributes) * 2 + 1, data)
data.append(1);
self.writeAttributes(streamOpenAttributes, data)
return data
def protocolTreeNodeToBytes(self, node):
outBytes = []
self.writeInternal(node, outBytes)
return outBytes
def writeInternal(self, node, data):
x = 1 + \
(0 if node.attributes is None else len(node.attributes) * 2) + \
(0 if not node.hasChildren() else 1) + \
(0 if node.data is None else 1)
self.writeListStart(x, data)
self.writeString(node.tag, data)
self.writeAttributes(node.attributes, data);
if node.data is not None:
self.writeBytes(node.data, data)
if node.hasChildren():
self.writeListStart(len(node.children), data);
for c in node.children:
self.writeInternal(c, data);
def writeAttributes(self, attributes, data):
if attributes is not None:
for key, value in attributes.items():
self.writeString(key, data);
self.writeString(value, data, True);
def writeBytes(self, bytes_, data, packed = False):
bytes__ = []
for b in bytes_:
if type(b) is int:
bytes__.append(b)
else:
bytes__.append(ord(b))
size = len(bytes__)
toWrite = bytes__
if size >= 0x100000:
data.append(254)
self.writeInt31(size, data)
elif size >= 0x100:
data.append(253)
self.writeInt20(size, data)
else:
r = None
if packed:
if size < 128:
r = self.tryPackAndWriteHeader(255, bytes__, data)
if r is None:
r = self.tryPackAndWriteHeader(251, bytes__, data)
if r is None:
data.append(252)
self.writeInt8(size, data)
else:
toWrite = r
data.extend(toWrite)
def writeInt8(self, v, data):
data.append(v & 0xFF)
def writeInt16(self, v, data):
data.append((v & 0xFF00) >> 8);
data.append((v & 0xFF) >> 0);
def writeInt20(self, v, data):
data.append((0xF0000 & v) >> 16)
data.append((0xFF00 & v) >> 8)
data.append((v & 0xFF) >> 0)
def writeInt24(self, v, data):
data.append((v & 0xFF0000) >> 16)
data.append((v & 0xFF00) >> 8)
data.append((v & 0xFF) >> 0)
def writeInt31(self, v, data):
data.append((0x7F000000 & v) >> 24)
data.append((0xFF0000 & v) >> 16)
data.append((0xFF00 & v) >> 8)
data.append((v & 0xFF) >> 0)
def writeListStart(self, i, data):
if i == 0:
data.append(0)
elif i < 256:
data.append(248)
self.writeInt8(i, data)
else:
data.append(249)
self.writeInt16(i, data)
def writeToken(self, token, data):
if token <= 255 and token >=0:
data.append(token)
else:
raise ValueError("Invalid token: %s" % token)
def writeString(self, tag, data, packed = False):
tok = self.tokenDictionary.getIndex(tag)
if tok:
index, secondary = tok
if secondary:
self.writeToken(236, data)
self.writeToken(index, data)
else:
at = '@'.encode() if type(tag) == bytes else '@'
try:
atIndex = tag.index(at)
if atIndex < 1:
raise ValueError("atIndex < 1")
else:
server = tag[atIndex+1:]
user = tag[0:atIndex]
self.writeJid(user, server, data)
except ValueError:
self.writeBytes(self.encodeString(tag), data, packed)
def encodeString(self, string):
res = []
if type(string) == bytes:
for char in string:
res.append(char)
else:
for char in string:
res.append(ord(char))
return res;
def writeJid(self, user, server, data):
data.append(250)
if user is not None:
self.writeString(user, data, True)
else:
self.writeToken(0, data)
self.writeString(server, data)
def tryPackAndWriteHeader(self, v, headerData, data):
size = len(headerData)
if size >= 128:
return None
arr = [0] * int((size + 1) / 2)
for i in range(0, size):
packByte = self.packByte(v, headerData[i])
if packByte == -1:
arr = []
break
n2 = int(i / 2)
arr[n2] |= (packByte << 4 * (1 - i % 2))
if len(arr) > 0:
if size % 2 == 1:
arr[-1] |= 15 #0xF
data.append(v)
self.writeInt8(size %2 << 7 | len(arr), data)
return arr
return None
def packByte(self, v, n2):
if v == 251:
return self.packHex(n2)
if v == 255:
return self.packNibble(n2)
return -1
def packHex(self, n):
if n in range(48, 58):
return n - 48
if n in range(65, 71):
return 10 + (n - 65)
return -1
def packNibble(self, n):
if n in (45, 46):
return 10 + (n - 45)
if n in range(48, 58):
return n - 48
return -1
yowsup-2.5.7/yowsup/layers/coder/layer.py 0000664 0000000 0000000 00000002670 13221545743 0020535 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, EventCallback
from yowsup.layers.network import YowNetworkLayer
from .encoder import WriteEncoder
from .decoder import ReadDecoder
from .tokendictionary import TokenDictionary
class YowCoderLayer(YowLayer):
PROP_DOMAIN = "org.openwhatsapp.yowsup.prop.domain"
PROP_RESOURCE = "org.openwhatsapp.yowsup.prop.resource"
def __init__(self):
YowLayer.__init__(self)
tokenDictionary = TokenDictionary()
self.writer = WriteEncoder(tokenDictionary)
self.reader = ReadDecoder(tokenDictionary)
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, event):
self.writer.reset()
self.reader.reset()
streamStartBytes = self.writer.getStreamStartBytes(
self.getProp(self.__class__.PROP_DOMAIN),
self.getProp(self.__class__.PROP_RESOURCE)
)
for i in range(0, 4):
self.write(streamStartBytes.pop(0))
self.write(streamStartBytes)
def send(self, data):
self.write(self.writer.protocolTreeNodeToBytes(data))
def receive(self, data):
node = self.reader.getProtocolTreeNode(data)
if node:
self.toUpper(node)
def write(self, i):
if(type(i) in(list, tuple)):
self.toLower(bytearray(i))
else:
self.toLower(bytearray([i]))
def __str__(self):
return "Coder Layer" yowsup-2.5.7/yowsup/layers/coder/test_decoder.py 0000664 0000000 0000000 00000001426 13221545743 0022063 0 ustar 00root root 0000000 0000000 import unittest
from yowsup.layers.coder.decoder import ReadDecoder
from yowsup.layers.coder.tokendictionary import TokenDictionary
from yowsup.structs import ProtocolTreeNode
class DecoderTest(unittest.TestCase):
def setUp(self):
self.decoder = ReadDecoder(TokenDictionary())
self.decoder.streamStarted = True
def test_decode(self):
data = [248, 6, 95, 179, 252, 3, 120, 121, 122, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 248, 1, 248, 4, 93,
236, 104, 255, 130, 18, 63, 252, 6, 49, 50, 51, 52, 53, 54]
node = self.decoder.getProtocolTreeNode(data)
targetNode = ProtocolTreeNode("message", {"form": "abc", "to":"xyz"}, [ProtocolTreeNode("media", {"width" : "123"}, data="123456")])
self.assertEqual(node, targetNode)
yowsup-2.5.7/yowsup/layers/coder/test_encoder.py 0000664 0000000 0000000 00000001734 13221545743 0022077 0 ustar 00root root 0000000 0000000 import unittest
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.coder.encoder import WriteEncoder
from yowsup.layers.coder.tokendictionary import TokenDictionary
class EncoderTest(unittest.TestCase):
def setUp(self):
self.res = []
self.encoder = WriteEncoder(TokenDictionary())
def test_encode(self):
node = ProtocolTreeNode("message", {"form": "abc", "to":"xyz"}, [ProtocolTreeNode("media", {"width" : "123"}, data="123456")])
result = self.encoder.protocolTreeNodeToBytes(node)
self.assertTrue(result in (
[248, 6, 95, 179, 252, 3, 120, 121, 122, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 248, 1, 248, 4, 93,
236, 104, 255, 130, 18, 63, 252, 6, 49, 50, 51, 52, 53, 54],
[248, 6, 95, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 179, 252, 3, 120, 121, 122, 248, 1, 248, 4, 93,
236, 104, 255, 130, 18, 63, 252, 6, 49, 50, 51, 52, 53, 54]
)
)
yowsup-2.5.7/yowsup/layers/coder/test_tokendictionary.py 0000664 0000000 0000000 00000001343 13221545743 0023662 0 ustar 00root root 0000000 0000000 from yowsup.layers.coder.tokendictionary import TokenDictionary
import unittest
class TokenDictionaryTest(unittest.TestCase):
def setUp(self):
self.tokenDictionary = TokenDictionary()
def test_getToken(self):
self.assertEqual(self.tokenDictionary.getToken(80), "iq")
def test_getIndex(self):
self.assertEqual(self.tokenDictionary.getIndex("iq"), (80, False))
def test_getSecondaryToken(self):
self.assertEqual(self.tokenDictionary.getToken(238), "amrnb")
def test_getSecondaryTokenExplicit(self):
self.assertEqual(self.tokenDictionary.getToken(11, True), "wmv")
def test_getSecondaryIndex(self):
self.assertEqual(self.tokenDictionary.getIndex("wmv"), (11, True)) yowsup-2.5.7/yowsup/layers/coder/tokendictionary.py 0000664 0000000 0000000 00000026663 13221545743 0022637 0 ustar 00root root 0000000 0000000 class TokenDictionary:
def __init__(self):
self.dictionary = [
'',
'',
'',
'account',
'ack',
'action',
'active',
'add',
'after',
'all',
'allow',
'apple',
'audio',
'auth',
'author',
'available',
'bad-protocol',
'bad-request',
'before',
'bits',
'body',
'broadcast',
'cancel',
'category',
'challenge',
'chat',
'clean',
'code',
'composing',
'config',
'contacts',
'count',
'create',
'creation',
'debug',
'default',
'delete',
'delivery',
'delta',
'deny',
'digest',
'dirty',
'duplicate',
'elapsed',
'enable',
'encoding',
'encrypt',
'error',
'event',
'expiration',
'expired',
'fail',
'failure',
'false',
'favorites',
'feature',
'features',
'feature-not-implemented',
'field',
'file',
'filehash',
'first',
'free',
'from',
'g.us',
'gcm',
'get',
'google',
'group',
'groups',
'groups_v2',
'http://etherx.jabber.org/streams',
'http://jabber.org/protocol/chatstates',
'ib',
'id',
'image',
'img',
'index',
'internal-server-error',
'ip',
'iq',
'item-not-found',
'item',
'jabber:iq:last',
'jabber:iq:privacy',
'jabber:x:event',
'jid',
'kind',
'last',
'leave',
'list',
'max',
'mechanism',
'media',
'message_acks',
'message',
'method',
'microsoft',
'mimetype',
'missing',
'modify',
'msg',
'mute',
'name',
'nokia',
'none',
'not-acceptable',
'not-allowed',
'not-authorized',
'notification',
'notify',
'off',
'offline',
'order',
'owner',
'owning',
'p_o',
'p_t',
'paid',
'participant',
'participants',
'participating',
'paused',
'picture',
'pin',
'ping',
'pkmsg',
'platform',
'port',
'presence',
'preview',
'probe',
'prop',
'props',
'qcount',
'query',
'raw',
'read',
'readreceipts',
'reason',
'receipt',
'relay',
'remote-server-timeout',
'remove',
'request',
'required',
'resource-constraint',
'resource',
'response',
'result',
'retry',
'rim',
's_o',
's_t',
's.us',
's.whatsapp.net',
'seconds',
'server-error',
'server',
'service-unavailable',
'set',
'show',
'silent',
'size',
'skmsg',
'stat',
'state',
'status',
'stream:error',
'stream:features',
'subject',
'subscribe',
'success',
'sync',
't',
'text',
'timeout',
'timestamp',
'tizen',
'to',
'true',
'type',
'unavailable',
'unsubscribe',
'upgrade',
'uri',
'url',
'urn:ietf:params:xml:ns:xmpp-sasl',
'urn:ietf:params:xml:ns:xmpp-stanzas',
'urn:ietf:params:xml:ns:xmpp-streams',
'urn:xmpp:ping',
'urn:xmpp:whatsapp:account',
'urn:xmpp:whatsapp:dirty',
'urn:xmpp:whatsapp:mms',
'urn:xmpp:whatsapp:push',
'urn:xmpp:whatsapp',
'user',
'user-not-found',
'v',
'value',
'version',
'voip',
'w:g',
'w:p:r',
'w:p',
'w:profile:picture',
'w',
'wait',
'WAUTH-2',
'xmlns:stream',
'xmlns',
'1',
'chatstate',
'crypto',
'phash',
'enc',
'class',
'off_cnt',
'w:g2',
'promote',
'demote',
'creator',
'background',
'backoff',
'chunked',
'context',
'full',
'in',
'interactive',
'out',
'registration',
'sid',
'urn:xmpp:whatsapp:sync',
'flt',
's16',
'u8',
]
self.secondaryDictionary = [
'adpcm',
'amrnb',
'amrwb',
'mp3',
'pcm',
'qcelp',
'wma',
'h263',
'h264',
'jpeg',
'mpeg4',
'wmv',
'audio/3gpp',
'audio/aac',
'audio/amr',
'audio/mp4',
'audio/mpeg',
'audio/ogg',
'audio/qcelp',
'audio/wav',
'audio/webm',
'audio/x-caf',
'audio/x-ms-wma',
'image/gif',
'image/jpeg',
'image/png',
'video/3gpp',
'video/avi',
'video/mp4',
'video/mpeg',
'video/quicktime',
'video/x-flv',
'video/x-ms-asf',
'302',
'400',
'401',
'402',
'403',
'404',
'405',
'406',
'407',
'409',
'410',
'500',
'501',
'503',
'504',
'abitrate',
'acodec',
'app_uptime',
'asampfmt',
'asampfreq',
'clear',
'conflict',
'conn_no_nna',
'cost',
'currency',
'duration',
'extend',
'fps',
'g_notify',
'g_sound',
'gone',
'google_play',
'hash',
'height',
'invalid',
'jid-malformed',
'latitude',
'lc',
'lg',
'live',
'location',
'log',
'longitude',
'max_groups',
'max_participants',
'max_subject',
'mode',
'napi_version',
'normalize',
'orighash',
'origin',
'passive',
'password',
'played',
'policy-violation',
'pop_mean_time',
'pop_plus_minus',
'price',
'pricing',
'redeem',
'Replaced by new connection',
'resume',
'signature',
'sound',
'source',
'system-shutdown',
'username',
'vbitrate',
'vcard',
'vcodec',
'video',
'width',
'xml-not-well-formed',
'checkmarks',
'image_max_edge',
'image_max_kbytes',
'image_quality',
'ka',
'ka_grow',
'ka_shrink',
'newmedia',
'library',
'caption',
'forward',
'c0',
'c1',
'c2',
'c3',
'clock_skew',
'cts',
'k0',
'k1',
'login_rtt',
'm_id',
'nna_msg_rtt',
'nna_no_off_count',
'nna_offline_ratio',
'nna_push_rtt',
'no_nna_con_count',
'off_msg_rtt',
'on_msg_rtt',
'stat_name',
'sts',
'suspect_conn',
'lists',
'self',
'qr',
'web',
'w:b',
'recipient',
'w:stats',
'forbidden',
'max_list_recipients',
'en-AU',
'en-GB',
'es-MX',
'pt-PT',
'zh-Hans',
'zh-Hant',
'relayelection',
'relaylatency',
'interruption',
'Bell.caf',
'Boing.caf',
'Glass.caf',
'Harp.caf',
'TimePassing.caf',
'Tri-tone.caf',
'Xylophone.caf',
'aurora.m4r',
'bamboo.m4r',
'chord.m4r',
'circles.m4r',
'complete.m4r',
'hello.m4r',
'input.m4r',
'keys.m4r',
'note.m4r',
'popcorn.m4r',
'pulse.m4r',
'synth.m4r',
'Apex.m4r',
'Beacon.m4r',
'Bulletin.m4r',
'By The Seaside.m4r',
'Chimes.m4r',
'Circuit.m4r',
'Constellation.m4r',
'Cosmic.m4r',
'Crystals.m4r',
'Hillside.m4r',
'Illuminate.m4r',
'Night Owl.m4r',
'Opening.m4r',
'Playtime.m4r',
'Presto.m4r',
'Radar.m4r',
'Radiate.m4r',
'Ripples.m4r',
'Sencha.m4r',
'Signal.m4r',
'Silk.m4r',
'Slow Rise.m4r',
'Stargaze.m4r',
'Summit.m4r',
'Twinkle.m4r',
'Uplift.m4r',
'Waves.m4r',
'eligible',
'planned',
'current',
'future',
'disable',
'expire',
'start',
'stop',
'accuracy',
'speed',
'bearing',
'recording',
'key',
'identity',
'w:gp2',
'admin',
'locked',
'unlocked',
'new',
'battery',
'archive',
'adm',
'plaintext_size',
'plaintext_disabled',
'plaintext_reenable_threshold',
'compressed_size',
'delivered',
'everyone',
'transport',
'mspes',
'e2e_groups',
'e2e_images',
'encr_media',
'encrypt_v2',
'encrypt_image',
'encrypt_sends_push',
'force_long_connect',
'audio_opus',
'video_max_edge',
'call-id',
'call',
'preaccept',
'accept',
'offer',
'reject',
'busy',
'te',
'terminate',
'begin',
'end',
'opus',
'rtt',
'token',
'priority',
'p2p',
'rate',
'amr',
'ptt',
'srtp',
'os',
'browser',
'encrypt_group_gen2'
]
def getToken(self, index, secondary = False):
targetDict = self.dictionary
if secondary:
targetDict = self.secondaryDictionary
elif index > 236 and index < (236 + len(self.secondaryDictionary)):
targetDict = self.secondaryDictionary
index = index - 237
if index < 0 or index > len(targetDict) - 1:
return None
return targetDict[index]
def getIndex(self, token):
if token in self.dictionary:
return (self.dictionary.index(token), False)
elif token in self.secondaryDictionary:
return (self.secondaryDictionary.index(token), True)
return None
yowsup-2.5.7/yowsup/layers/interface/ 0000775 0000000 0000000 00000000000 13221545743 0017706 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/interface/__init__.py 0000664 0000000 0000000 00000000100 13221545743 0022006 0 ustar 00root root 0000000 0000000 from .interface import YowInterfaceLayer, ProtocolEntityCallback yowsup-2.5.7/yowsup/layers/interface/interface.py 0000664 0000000 0000000 00000014277 13221545743 0022233 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers.protocol_media.protocolentities.iq_requestupload import RequestUploadIqProtocolEntity
from yowsup.layers.protocol_media.mediauploader import MediaUploader
from yowsup.layers.network.layer import YowNetworkLayer
from yowsup.layers.auth.protocolentities import StreamErrorProtocolEntity
from yowsup.layers import EventCallback
import inspect
import logging
logger = logging.getLogger(__name__)
class ProtocolEntityCallback(object):
def __init__(self, entityType):
self.entityType = entityType
def __call__(self, fn):
fn.entity_callback = self.entityType
return fn
class YowInterfaceLayer(YowLayer):
PROP_RECONNECT_ON_STREAM_ERR = "org.openwhatsapp.yowsup.prop.interface.reconnect_on_stream_error"
def __init__(self):
super(YowInterfaceLayer, self).__init__()
self.reconnect = False
self.entity_callbacks = {}
self.iqRegistry = {}
# self.receiptsRegistry = {}
members = inspect.getmembers(self, predicate=inspect.ismethod)
for m in members:
if hasattr(m[1], "entity_callback"):
fname = m[0]
fn = m[1]
self.entity_callbacks[fn.entity_callback] = getattr(self, fname)
def _sendIq(self, iqEntity, onSuccess = None, onError = None):
assert iqEntity.getTag() == "iq", "Expected *IqProtocolEntity in _sendIq, got %s" % iqEntity.getTag()
self.iqRegistry[iqEntity.getId()] = (iqEntity, onSuccess, onError)
self.toLower(iqEntity)
def processIqRegistry(self, entity):
"""
:type entity: IqProtocolEntity
"""
if entity.getTag() == "iq":
iq_id = entity.getId()
if iq_id in self.iqRegistry:
originalIq, successClbk, errorClbk = self.iqRegistry[iq_id]
del self.iqRegistry[iq_id]
if entity.getType() == IqProtocolEntity.TYPE_RESULT and successClbk:
successClbk(entity, originalIq)
elif entity.getType() == IqProtocolEntity.TYPE_ERROR and errorClbk:
errorClbk(entity, originalIq)
return True
return False
def getOwnJid(self, full = True):
return self.getLayerInterface(YowAuthenticationProtocolLayer).getUsername(full)
def connect(self):
self.getLayerInterface(YowNetworkLayer).connect()
def disconnect(self):
disconnectEvent = YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT)
self.broadcastEvent(disconnectEvent)
def send(self, data):
self.toLower(data)
def receive(self, entity):
if not self.processIqRegistry(entity):
entityType = entity.getTag()
if entityType in self.entity_callbacks:
self.entity_callbacks[entityType](entity)
else:
self.toUpper(entity)
@ProtocolEntityCallback("stream:error")
def onStreamError(self, streamErrorEntity):
logger.error(streamErrorEntity)
if self.getProp(self.__class__.PROP_RECONNECT_ON_STREAM_ERR, True):
if streamErrorEntity.getErrorType() == StreamErrorProtocolEntity.TYPE_CONFLICT:
logger.warn("Not reconnecting because you signed in in another location")
else:
logger.info("Initiating reconnect")
self.reconnect = True
else:
logger.warn("Not reconnecting because property %s is not set" % self.__class__.PROP_RECONNECT_ON_STREAM_ERR)
self.toUpper(streamErrorEntity)
self.disconnect()
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, yowLayerEvent):
self.reconnect = False
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
def onDisconnected(self, yowLayerEvent):
if self.reconnect:
self.reconnect = False
self.connect()
def _sendMediaMessage(self, builder, success, error = None, progress = None):
# axolotlIface = self.getLayerInterface(YowAxolotlLayer)
# if axolotlIface:
# axolotlIface.encryptMedia(builder)
iq = RequestUploadIqProtocolEntity(builder.mediaType, filePath = builder.getFilepath(), encrypted = builder.isEncrypted())
successFn = lambda resultEntity, requestUploadEntity: self.__onRequestUploadSuccess(resultEntity, requestUploadEntity, builder, success, error, progress)
errorFn = lambda errorEntity, requestUploadEntity: self.__onRequestUploadError(errorEntity, requestUploadEntity, error)
self._sendIq(iq, successFn, errorFn)
def __onRequestUploadSuccess(self, resultRequestUploadIqProtocolEntity, requestUploadEntity, builder, success, error = None, progress = None):
if(resultRequestUploadIqProtocolEntity.isDuplicate()):
return success(builder.build(resultRequestUploadIqProtocolEntity.getUrl(), resultRequestUploadIqProtocolEntity.getIp()))
else:
successFn = lambda path, jid, url: self.__onMediaUploadSuccess(builder, url, resultRequestUploadIqProtocolEntity.getIp(), success)
errorFn = lambda path, jid, errorText: self.__onMediaUploadError(builder, errorText, error)
mediaUploader = MediaUploader(builder.jid, self.getOwnJid(), builder.getFilepath(),
resultRequestUploadIqProtocolEntity.getUrl(),
resultRequestUploadIqProtocolEntity.getResumeOffset(),
successFn, errorFn, progress, async=True)
mediaUploader.start()
def __onRequestUploadError(self, errorEntity, requestUploadEntity, builder, error = None):
if error:
return error(errorEntity.code, errorEntity.text, errorEntity.backoff)
def __onMediaUploadSuccess(self, builder, url, ip, successClbk):
messageNode = builder.build(url, ip)
return successClbk(messageNode)
def __onMediaUploadError(self, builder, errorText, errorClbk = None):
if errorClbk:
return errorClbk(0, errorText, 0)
def __str__(self):
return "Interface Layer"
yowsup-2.5.7/yowsup/layers/logger/ 0000775 0000000 0000000 00000000000 13221545743 0017225 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/logger/__init__.py 0000664 0000000 0000000 00000000042 13221545743 0021332 0 ustar 00root root 0000000 0000000 from .layer import YowLoggerLayer
yowsup-2.5.7/yowsup/layers/logger/layer.py 0000664 0000000 0000000 00000000753 13221545743 0020720 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer
import logging
logger = logging.getLogger(__name__)
class YowLoggerLayer(YowLayer):
def send(self, data):
ldata = list(data) if type(data) is bytearray else data
logger.debug("tx:\n%s" % ldata)
self.toLower(data)
def receive(self, data):
ldata = list(data) if type(data) is bytearray else data
logger.debug("rx:\n%s" % ldata)
self.toUpper(data)
def __str__(self):
return "Logger Layer" yowsup-2.5.7/yowsup/layers/network/ 0000775 0000000 0000000 00000000000 13221545743 0017437 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/network/__init__.py 0000664 0000000 0000000 00000000043 13221545743 0021545 0 ustar 00root root 0000000 0000000 from .layer import YowNetworkLayer
yowsup-2.5.7/yowsup/layers/network/layer.py 0000664 0000000 0000000 00000010157 13221545743 0021131 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, EventCallback
from yowsup.common.http.httpproxy import HttpProxy
from yowsup.layers.network.layer_interface import YowNetworkLayerInterface
import asyncore, socket, logging
logger = logging.getLogger(__name__)
class YowNetworkLayer(YowLayer, asyncore.dispatcher_with_send):
'''
send: bytearray -> None
receive: bytearray -> bytearray
'''
EVENT_STATE_CONNECT = "org.openwhatsapp.yowsup.event.network.connect"
EVENT_STATE_DISCONNECT = "org.openwhatsapp.yowsup.event.network.disconnect"
EVENT_STATE_CONNECTED = "org.openwhatsapp.yowsup.event.network.connected"
EVENT_STATE_DISCONNECTED = "org.openwhatsapp.yowsup.event.network.disconnected"
PROP_ENDPOINT = "org.openwhatsapp.yowsup.prop.endpoint"
PROP_NET_READSIZE = "org.openwhatsapp.yowsup.prop.net.readSize"
STATE_DISCONNECTED = 0
STATE_CONNECTING = 1
STATE_CONNECTED = 2
STATE_DISCONNECTING = 3
def __init__(self):
asyncore.dispatcher.__init__(self)
self.state = self.__class__.STATE_DISCONNECTED
YowLayer.__init__(self)
self.interface = YowNetworkLayerInterface(self)
httpProxy = HttpProxy.getFromEnviron()
proxyHandler = None
if httpProxy != None:
logger.debug("HttpProxy initialize: %s" % httpProxy)
def onConnect():
logger.debug("HttpProxy connected")
self.proxyHandler = None
self.handle_connect()
proxyHandler = httpProxy.handler()
proxyHandler.onConnect = onConnect
self.proxyHandler = proxyHandler
@EventCallback(EVENT_STATE_CONNECT)
def onConnect(self, ev):
self.createConnection()
return True
@EventCallback(EVENT_STATE_DISCONNECT)
def onDisconnect(self, ev):
self.destroyConnection(ev.getArg("reason"))
return True
def createConnection(self):
self.state = self.__class__.STATE_CONNECTING
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
self.out_buffer = bytearray()
endpoint = self.getProp(self.__class__.PROP_ENDPOINT)
logger.debug("Connecting to %s:%s" % endpoint)
if self.proxyHandler != None:
logger.debug("HttpProxy connect: %s:%d" % endpoint)
self.proxyHandler.connect(self, endpoint)
else:
try:
self.connect(endpoint)
except OSError as e:
self.handle_close(e)
def destroyConnection(self, reason = None):
self.state = self.__class__.STATE_DISCONNECTING
self.handle_close(reason or "Requested")
def getStatus(self):
return self.connected
def handle_connect(self):
self.state = self.__class__.STATE_CONNECTED
self.connected = True
if self.proxyHandler != None:
logger.debug("HttpProxy handle connect")
self.proxyHandler.send(self)
else:
self.emitEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_CONNECTED))
def handle_close(self, reason = "Connection Closed"):
if self.state != self.__class__.STATE_DISCONNECTED:
self.state = self.__class__.STATE_DISCONNECTED
self.connected = False
logger.debug("Disconnected, reason: %s" % reason)
self.emitEvent(YowLayerEvent(self.__class__.EVENT_STATE_DISCONNECTED, reason = reason, detached=True))
self.close()
def handle_error(self):
raise
def handle_read(self):
readSize = self.getProp(self.__class__.PROP_NET_READSIZE, 1024)
if self.proxyHandler != None:
data = self.proxyHandler.recv(self, readSize)
logger.debug("HttpProxy handle read: %s" % data)
else:
data = self.recv(readSize)
self.receive(data)
def send(self, data):
if self.connected:
self.out_buffer = self.out_buffer + data
self.initiate_send()
def receive(self, data):
self.toUpper(data)
def __str__(self):
return "Network Layer"
yowsup-2.5.7/yowsup/layers/network/layer_interface.py 0000664 0000000 0000000 00000000440 13221545743 0023143 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayerInterface
class YowNetworkLayerInterface(YowLayerInterface):
def connect(self):
self._layer.createConnection()
def disconnect(self):
self._layer.destroyConnection()
def getStatus(self):
return self._layer.getStatus() yowsup-2.5.7/yowsup/layers/protocol_acks/ 0000775 0000000 0000000 00000000000 13221545743 0020610 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_acks/__init__.py 0000664 0000000 0000000 00000000047 13221545743 0022722 0 ustar 00root root 0000000 0000000 from .layer import YowAckProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_acks/layer.py 0000664 0000000 0000000 00000001021 13221545743 0022270 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayer
from .protocolentities import *
class YowAckProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"ack": (self.recvAckNode, self.sendAckEntity)
}
super(YowAckProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Ack Layer"
def sendAckEntity(self, entity):
self.entityToLower(entity)
def recvAckNode(self, node):
self.toUpper(IncomingAckProtocolEntity.fromProtocolTreeNode(node))
yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0024216 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/__init__.py 0000664 0000000 0000000 00000000212 13221545743 0026322 0 ustar 00root root 0000000 0000000 from .ack import AckProtocolEntity
from .ack_incoming import IncomingAckProtocolEntity
from .ack_outgoing import OutgoingAckProtocolEntity yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/ack.py 0000664 0000000 0000000 00000001743 13221545743 0025333 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class AckProtocolEntity(ProtocolEntity):
'''
'''
def __init__(self, _id, _class):
super(AckProtocolEntity, self).__init__("ack")
self._id = _id
self._class = _class
def getId(self):
return self._id
def getClass(self):
return self._class
def toProtocolTreeNode(self):
attribs = {
"id" : self._id,
"class" : self._class,
}
return self._createProtocolTreeNode(attribs, None, data = None)
def __str__(self):
out = "ACK:\n"
out += "ID: %s\n" % self._id
out += "Class: %s\n" % self._class
return out
@staticmethod
def fromProtocolTreeNode(node):
return AckProtocolEntity(
node.getAttributeValue("id"),
node.getAttributeValue("class")
)
yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/ack_incoming.py 0000664 0000000 0000000 00000002430 13221545743 0027210 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .ack import AckProtocolEntity
class IncomingAckProtocolEntity(AckProtocolEntity):
'''
'''
def __init__(self, _id, _class, _from, timestamp):
super(IncomingAckProtocolEntity, self).__init__(_id, _class)
self.setIncomingData(_from, timestamp)
def setIncomingData(self, _from, timestamp):
self._from = _from
self.timestamp = timestamp
def toProtocolTreeNode(self):
node = super(IncomingAckProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("from", self._from)
node.setAttribute("t", self.timestamp)
return node
def __str__(self):
out = super(IncomingAckProtocolEntity, self).__str__()
out += "From: %s\n" % self._from
out += "timestamp: %s\n" % self.timestamp
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = AckProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = IncomingAckProtocolEntity
entity.setIncomingData(
node.getAttributeValue("from"),
node.getAttributeValue("t")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/ack_outgoing.py 0000664 0000000 0000000 00000003176 13221545743 0027250 0 ustar 00root root 0000000 0000000 from .ack import AckProtocolEntity
class OutgoingAckProtocolEntity(AckProtocolEntity):
'''
'''
def __init__(self, _id, _class, _type, to, participant = None):
super(OutgoingAckProtocolEntity, self).__init__(_id, _class)
self.setOutgoingData(_type, to, participant)
def setOutgoingData(self, _type, _to, _participant):
self._type = _type
self._to = _to
self._participant = _participant
def toProtocolTreeNode(self):
node = super(OutgoingAckProtocolEntity, self).toProtocolTreeNode()
if self._type:
node.setAttribute("type", self._type)
node.setAttribute("to", self._to)
if self._participant:
node.setAttribute("participant", self._participant)
return node
def __str__(self):
out = super(OutgoingAckProtocolEntity, self).__str__()
out += "Type: %s\n" % self._type
out += "To: %s\n" % self._to
if self._participant:
out += "Participant: %s\n" % self._participant
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = AckProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = OutgoingAckProtocolEntity
entity.setOutgoingData(
node.getAttributeValue("type"),
node.getAttributeValue("to"),
node.getAttributeValue("participant")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/test_ack_incoming.py 0000664 0000000 0000000 00000000746 13221545743 0030257 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_acks.protocolentities.ack_incoming import IncomingAckProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
import time
entity = IncomingAckProtocolEntity("12345", "message", "sender@s.whatsapp.com", int(time.time()))
class IncomingAckProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = IncomingAckProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_acks/protocolentities/test_ack_outgoing.py 0000664 0000000 0000000 00000000705 13221545743 0030302 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_acks.protocolentities.ack_outgoing import OutgoingAckProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = OutgoingAckProtocolEntity("12345", "receipt", "delivery", "to_jid")
class OutgoingAckProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = OutgoingAckProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_acks/test_layer.py 0000664 0000000 0000000 00000001124 13221545743 0023333 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayerTest
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.protocol_acks.protocolentities.test_ack_incoming import entity as incomingAckEntity
from yowsup.layers.protocol_acks.protocolentities.test_ack_outgoing import entity as outgoingAckEntity
class YowAckProtocolLayerTest(YowProtocolLayerTest, YowAckProtocolLayer):
def setUp(self):
YowAckProtocolLayer.__init__(self)
def test_receive(self):
self.assertReceived(incomingAckEntity)
def test_send(self):
self.assertSent(outgoingAckEntity)
yowsup-2.5.7/yowsup/layers/protocol_calls/ 0000775 0000000 0000000 00000000000 13221545743 0020765 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_calls/__init__.py 0000664 0000000 0000000 00000000051 13221545743 0023072 0 ustar 00root root 0000000 0000000 from .layer import YowCallsProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_calls/layer.py 0000664 0000000 0000000 00000002137 13221545743 0022456 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayer
from .protocolentities import *
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
class YowCallsProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"call": (self.recvCall, self.sendCall)
}
super(YowCallsProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "call Layer"
def sendCall(self, entity):
if entity.getTag() == "call":
self.toLower(entity.toProtocolTreeNode())
def recvCall(self, node):
entity = CallProtocolEntity.fromProtocolTreeNode(node)
if entity.getType() == "offer":
receipt = OutgoingReceiptProtocolEntity(node["id"], node["from"], callId = entity.getCallId())
self.toLower(receipt.toProtocolTreeNode())
else:
ack = OutgoingAckProtocolEntity(node["id"], "call", None, node["from"])
self.toLower(ack.toProtocolTreeNode())
self.toUpper(entity)
yowsup-2.5.7/yowsup/layers/protocol_calls/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0024373 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_calls/protocolentities/__init__.py 0000664 0000000 0000000 00000000066 13221545743 0026506 0 ustar 00root root 0000000 0000000 from .call import CallProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_calls/protocolentities/call.py 0000664 0000000 0000000 00000007365 13221545743 0025673 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class CallProtocolEntity(ProtocolEntity):
'''
'''
def __init__(self, _id, _type, timestamp, notify = None, offline = None, retry = None, e = None, callId = None, _from = None, _to = None):
super(CallProtocolEntity, self).__init__("call")
self._id = _id or self._generateId()
self._type = _type
self._from = _from
self._to = _to
self.timestamp = int(timestamp)
self.notify = notify
self.offline = offline == "1"
self.retry = retry
self.e = e
self.callId = callId
def __str__(self):
out = "Call\n"
if self.getFrom() is not None:
out += "From: %s\n" % self.getFrom()
if self.getTo() is not None:
out += "To: %s\n" % self.getTo()
if self.getType() is not None:
out += "Type: %s\n" % self.getType()
if self.getCallId() is not None:
out += "Call ID: %s\n" % self.getCallId()
return out
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def getTo(self):
return self._to
def getId(self):
return self._id
def getType(self):
return self._type
def getCallId(self):
return self.callId
def getTimestamp(self):
return self.timestamp
def toProtocolTreeNode(self):
children = []
attribs = {
"t" : str(self.timestamp),
"offline" : "1" if self.offline else "0",
"id" : self._id,
}
if self._from is not None:
attribs["from"] = self._from
if self._to is not None:
attribs["to"] = self._to
if self.retry is not None:
attribs["retry"] = self.retry
if self.e is not None:
attribs["e"] = self.e
if self.notify is not None:
attribs["notify"] = self.notify
if self._type in ["offer", "transport", "relaylatency", "reject", "terminate"]:
child = ProtocolTreeNode(self._type, {"call-id": self.callId})
children.append(child)
return self._createProtocolTreeNode(attribs, children = children, data = None)
@staticmethod
def fromProtocolTreeNode(node):
(_type, callId) = [None] * 2
offer = node.getChild("offer")
transport = node.getChild("transport")
relaylatency = node.getChild("relaylatency")
reject = node.getChild("reject")
terminate = node.getChild("terminate")
if offer:
_type = "offer"
callId = offer.getAttributeValue("call-id")
elif transport:
_type = "transport"
callId = transport.getAttributeValue("call-id")
elif relaylatency:
_type = "relaylatency"
callId = relaylatency.getAttributeValue("call-id")
elif reject:
_type = "reject"
callId = reject.getAttributeValue("call-id")
elif terminate:
_type = "terminate"
callId = terminate.getAttributeValue("call-id")
return CallProtocolEntity(
node.getAttributeValue("id"),
_type,
node.getAttributeValue("t"),
node.getAttributeValue("notify"),
node.getAttributeValue("offline"),
node.getAttributeValue("retry"),
node.getAttributeValue("e"),
callId,
node.getAttributeValue("from"),
node.getAttributeValue("to")
)
yowsup-2.5.7/yowsup/layers/protocol_calls/protocolentities/test_call.py 0000664 0000000 0000000 00000001226 13221545743 0026720 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_calls.protocolentities.call import CallProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class CallProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = CallProtocolEntity
children = [ProtocolTreeNode("offer", {"call-id": "call_id"})]
attribs = {
"t": "12345",
"from": "from_jid",
"offline": "0",
"id": "message_id",
"notify": "notify_name"
}
self.node = ProtocolTreeNode("call", attribs, children)
yowsup-2.5.7/yowsup/layers/protocol_chatstate/ 0000775 0000000 0000000 00000000000 13221545743 0021647 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_chatstate/__init__.py 0000664 0000000 0000000 00000000055 13221545743 0023760 0 ustar 00root root 0000000 0000000 from .layer import YowChatstateProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_chatstate/layer.py 0000664 0000000 0000000 00000001140 13221545743 0023331 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
class YowChatstateProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"chatstate": (self.recvChatstateNode, self.sendChatstateEntity)
}
super(YowChatstateProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Chatstate Layer"
def sendChatstateEntity(self, entity):
self.entityToLower(entity)
def recvChatstateNode(self, node):
self.toUpper(IncomingChatstateProtocolEntity.fromProtocolTreeNode(node))
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025255 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/__init__.py 0000664 0000000 0000000 00000000257 13221545743 0027372 0 ustar 00root root 0000000 0000000 from .chatstate import ChatstateProtocolEntity
from .chatstate_incoming import IncomingChatstateProtocolEntity
from .chatstate_outgoing import OutgoingChatstateProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/chatstate.py 0000664 0000000 0000000 00000002322 13221545743 0027606 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class ChatstateProtocolEntity(ProtocolEntity):
'''
INCOMING
<{{composing|paused}}>{{composing|paused}}>
OUTGOING
<{{composing|paused}}>{{composing|paused}}>
'''
STATE_TYPING = "composing"
STATE_PAUSED = "paused"
STATES = (STATE_TYPING, STATE_PAUSED)
def __init__(self, _state):
super(ChatstateProtocolEntity, self).__init__("chatstate")
assert _state in self.__class__.STATES, "Expected chat state to be in %s, got %s" % (self.__class__.STATES, _state)
self._state = _state
def getState(self):
return self._state
def toProtocolTreeNode(self):
node = self._createProtocolTreeNode({}, None, data = None)
node.addChild(ProtocolTreeNode(self._state))
return node
def __str__(self):
out = "CHATSTATE:\n"
out += "State: %s\n" % self._state
return out
@staticmethod
def fromProtocolTreeNode(node):
return ChatstateProtocolEntity(
node.getAllChildren()[0].tag,
)
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/chatstate_incoming.py 0000664 0000000 0000000 00000002316 13221545743 0031474 0 ustar 00root root 0000000 0000000 from .chatstate import ChatstateProtocolEntity
class IncomingChatstateProtocolEntity(ChatstateProtocolEntity):
'''
INCOMING
<{{composing|paused}}>{{composing|paused}}>
OUTGOING
<{{composing|paused}}>{{composing|paused}}>
'''
def __init__(self, _state, _from):
super(IncomingChatstateProtocolEntity, self).__init__(_state)
self.setIncomingData(_from)
def setIncomingData(self, _from):
self._from = _from
def toProtocolTreeNode(self):
node = super(IncomingChatstateProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("from", self._from)
return node
def __str__(self):
out = super(IncomingChatstateProtocolEntity, self).__str__()
out += "From: %s\n" % self._from
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = ChatstateProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = IncomingChatstateProtocolEntity
entity.setIncomingData(
node.getAttributeValue("from"),
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/chatstate_outgoing.py 0000664 0000000 0000000 00000002272 13221545743 0031525 0 ustar 00root root 0000000 0000000 from .chatstate import ChatstateProtocolEntity
class OutgoingChatstateProtocolEntity(ChatstateProtocolEntity):
'''
INCOMING
<{{composing|paused}}>{{composing|paused}}>
OUTGOING
<{{composing|paused}}>{{composing|paused}}>
'''
def __init__(self, _state, _to):
super(OutgoingChatstateProtocolEntity, self).__init__(_state)
self.setOutgoingData(_to)
def setOutgoingData(self, _to):
self._to = _to
def toProtocolTreeNode(self):
node = super(OutgoingChatstateProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("to", self._to)
return node
def __str__(self):
out = super(OutgoingChatstateProtocolEntity, self).__str__()
out += "To: %s\n" % self._to
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = ChatstateProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = OutgoingChatstateProtocolEntity
entity.setOutgoingData(
node.getAttributeValue("to"),
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/test_chatstate_incoming.py 0000664 0000000 0000000 00000001002 13221545743 0032522 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_chatstate.protocolentities.chatstate_incoming import IncomingChatstateProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = IncomingChatstateProtocolEntity(IncomingChatstateProtocolEntity.STATE_TYPING, "jid@s.whatsapp.net")
class IncomingChatstateProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = IncomingChatstateProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_chatstate/protocolentities/test_chatstate_outgoing.py 0000664 0000000 0000000 00000001002 13221545743 0032552 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_chatstate.protocolentities.chatstate_outgoing import OutgoingChatstateProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = OutgoingChatstateProtocolEntity(OutgoingChatstateProtocolEntity.STATE_PAUSED, "jid@s.whatsapp.net")
class OutgoingChatstateProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = OutgoingChatstateProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_chatstate/test_layer.py 0000664 0000000 0000000 00000001366 13221545743 0024402 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayerTest
from yowsup.layers.protocol_chatstate import YowChatstateProtocolLayer
from yowsup.layers.protocol_chatstate.protocolentities import IncomingChatstateProtocolEntity, OutgoingChatstateProtocolEntity
class YowChatStateProtocolLayerTest(YowProtocolLayerTest, YowChatstateProtocolLayer):
def setUp(self):
YowChatstateProtocolLayer.__init__(self)
def test_send(self):
entity = OutgoingChatstateProtocolEntity(OutgoingChatstateProtocolEntity.STATE_PAUSED, "jid@s.whatsapp.net")
self.assertSent(entity)
def test_receive(self):
entity = IncomingChatstateProtocolEntity(IncomingChatstateProtocolEntity.STATE_TYPING, "jid@s.whatsapp.net")
self.assertReceived(entity) yowsup-2.5.7/yowsup/layers/protocol_contacts/ 0000775 0000000 0000000 00000000000 13221545743 0021505 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_contacts/__init__.py 0000664 0000000 0000000 00000000055 13221545743 0023616 0 ustar 00root root 0000000 0000000 from .layer import YowContactsIqProtocolLayer yowsup-2.5.7/yowsup/layers/protocol_contacts/layer.py 0000664 0000000 0000000 00000003320 13221545743 0023171 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from yowsup.common import YowConstants
from .protocolentities import *
class YowContactsIqProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"iq": (self.recvIq, self.sendIq),
"notification": (self.recvNotification, None)
}
super(YowContactsIqProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Iq Layer"
def recvNotification(self, node):
if node["type"] == "contacts":
if node.getChild("remove"):
self.toUpper(RemoveContactNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("add"):
self.toUpper(AddContactNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("update"):
self.toUpper(UpdateContactNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("sync"):
self.toUpper(ContactsSyncNotificationProtocolEntity.fromProtocolTreeNode(node))
else:
self.raiseErrorForNode(node)
def recvIq(self, node):
if node["type"] == "result" and node.getChild("sync"):
self.toUpper(ResultSyncIqProtocolEntity.fromProtocolTreeNode(node))
elif node["type"] == "result" and node.getChild("status"):
self.toUpper(ResultStatusesIqProtocolEntity.fromProtocolTreeNode(node))
def sendIq(self, entity):
if entity.getXmlns() == "urn:xmpp:whatsapp:sync":
self.toLower(entity.toProtocolTreeNode())
elif entity.getXmlns() == GetStatusesIqProtocolEntity.XMLNS:
self.toLower(entity.toProtocolTreeNode())
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025113 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/__init__.py 0000664 0000000 0000000 00000001107 13221545743 0027223 0 ustar 00root root 0000000 0000000 from .iq_sync import SyncIqProtocolEntity
from .iq_sync_get import GetSyncIqProtocolEntity
from .iq_sync_result import ResultSyncIqProtocolEntity
from .notification_contact_add import AddContactNotificationProtocolEntity
from .notification_contact_remove import RemoveContactNotificationProtocolEntity
from .notification_contact_update import UpdateContactNotificationProtocolEntity
from .notificiation_contacts_sync import ContactsSyncNotificationProtocolEntity
from .iq_statuses_get import GetStatusesIqProtocolEntity
from .iq_statuses_result import ResultStatusesIqProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/iq_statuses_get.py 0000664 0000000 0000000 00000003167 13221545743 0030677 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class GetStatusesIqProtocolEntity(IqProtocolEntity):
XMLNS = "status"
def __init__(self, jids, _id = None):
"""
Request the statuses of users. Should be sent once after login.
Args:
- jids: A list of jids representing the users whose statuses you are
trying to get.
"""
super(GetStatusesIqProtocolEntity, self).__init__(self.__class__.XMLNS, _id, _type = "get", to = YowConstants.WHATSAPP_SERVER)
self.setGetStatusesProps(jids)
def setGetStatusesProps(self, jids):
assert type(jids) is list, "jids must be a list of jids"
self.jids = jids
def __str__(self):
out = super(GetStatusesIqProtocolEntity, self).__str__()
out += "Numbers: %s\n" % (",".join(self.numbers))
return out
def toProtocolTreeNode(self):
users = [ProtocolTreeNode("user", {'jid': jid}) for jid in self.jids]
node = super(GetStatusesIqProtocolEntity, self).toProtocolTreeNode()
statusNode = ProtocolTreeNode("status", None, users)
node.addChild(statusNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = GetStatusesIqProtocolEntity
statusNode = node.getChild("status")
userNodes = statusNode.getAllChildren()
jids = [user['jid'] for user in userNodes]
entity.setGetStatusesProps(jids)
return entity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/iq_statuses_result.py 0000664 0000000 0000000 00000003771 13221545743 0031437 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .iq_sync import SyncIqProtocolEntity
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
class ResultStatusesIqProtocolEntity(IqProtocolEntity):
'''
{status message}
HEX:{status message in hex}
{status message}
HEX:{status message in hex}
'''
XMLNS = 'status'
def __init__(self, _id, _from, statuses):
super(ResultStatusesIqProtocolEntity, self).__init__(self.__class__.XMLNS, _id, 'result', _from=_from)
self.setResultStatusesProps(statuses)
def setResultStatusesProps(self, statuses):
assert type(statuses) is dict, "statuses must be dict"
self.statuses = statuses
def __str__(self):
out = super(ResultStatusesIqProtocolEntity, self).__str__()
out += "Statuses: %s\n" % ','.join(jid + '(' + str(v) + ')' for jid, v in self.statuses.items())
return out
def toProtocolTreeNode(self):
node = super(ResultStatusesIqProtocolEntity, self).toProtocolTreeNode()
users = [ProtocolTreeNode('user', {'jid': jid, 't': t}, None, status) for jid, (status, t) in self.statuses.items()]
statusNode = ProtocolTreeNode('status', None, users)
node.addChild(statusNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
statusNode = node.getChild('status')
users = statusNode.getAllChildren()
statuses = dict()
for user in users:
statuses[user['jid']] = (user.getData(), user['t'])
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ResultStatusesIqProtocolEntity
entity.setResultStatusesProps(statuses)
return entity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/iq_sync.py 0000664 0000000 0000000 00000003557 13221545743 0027144 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
import time
class SyncIqProtocolEntity(IqProtocolEntity):
'''
'''
def __init__(self, _type, _id = None, sid = None, index = 0, last = True):
super(SyncIqProtocolEntity, self).__init__("urn:xmpp:whatsapp:sync", _id = _id, _type = _type)
self.setSyncProps(sid, index, last)
def setSyncProps(self, sid, index, last):
self.sid = sid if sid else str((int(time.time()) + 11644477200) * 10000000)
self.index = int(index)
self.last = last
def __str__(self):
out = super(SyncIqProtocolEntity, self).__str__()
out += "sid: %s\n" % self.sid
out += "index: %s\n" % self.index
out += "last: %s\n" % self.last
return out
def toProtocolTreeNode(self):
syncNodeAttrs = {
"sid": self.sid,
"index": str(self.index),
"last": "true" if self.last else "false"
}
syncNode = ProtocolTreeNode("sync", syncNodeAttrs)
node = super(SyncIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(syncNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
syncNode = node.getChild("sync")
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SyncIqProtocolEntity
entity.setSyncProps(
syncNode.getAttributeValue("sid"),
syncNode.getAttributeValue("index"),
syncNode.getAttributeValue("last")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/iq_sync_get.py 0000664 0000000 0000000 00000005274 13221545743 0030001 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from .iq_sync import SyncIqProtocolEntity
class GetSyncIqProtocolEntity(SyncIqProtocolEntity):
MODE_FULL = "full"
MODE_DELTA = "delta"
CONTEXT_REGISTRATION = "registration"
CONTEXT_INTERACTIVE = "interactive"
CONTEXTS = (CONTEXT_REGISTRATION, CONTEXT_INTERACTIVE)
MODES = (MODE_FULL, MODE_DELTA)
'''
{{num1}}
{{num2}}
'''
def __init__(self, numbers, mode = MODE_FULL, context = CONTEXT_INTERACTIVE, sid = None, index = 0, last = True):
super(GetSyncIqProtocolEntity, self).__init__("get", sid = sid, index = index, last = last)
self.setGetSyncProps(numbers, mode, context)
def setGetSyncProps(self, numbers, mode, context):
assert type(numbers) is list, "numbers must be a list"
assert mode in self.__class__.MODES, "mode must be in %s" % self.__class__.MODES
assert context in self.__class__.CONTEXTS, "context must be in %s" % self.__class__.CONTEXTS
self.numbers = numbers
self.mode = mode
self.context = context
def __str__(self):
out = super(GetSyncIqProtocolEntity, self).__str__()
out += "Mode: %s\n" % self.mode
out += "Context: %s\n" % self.context
out += "numbers: %s\n" % (",".join(self.numbers))
return out
def toProtocolTreeNode(self):
users = [ProtocolTreeNode("user", {}, None, number) for number in self.numbers]
node = super(GetSyncIqProtocolEntity, self).toProtocolTreeNode()
syncNode = node.getChild("sync")
syncNode.setAttribute("mode", self.mode)
syncNode.setAttribute("context", self.context)
syncNode.addChildren(users)
return node
@staticmethod
def fromProtocolTreeNode(node):
syncNode = node.getChild("sync")
userNodes = syncNode.getAllChildren()
numbers = [userNode.data for userNode in userNodes]
entity = SyncIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = GetSyncIqProtocolEntity
entity.setGetSyncProps(numbers,
syncNode.getAttributeValue("mode"),
syncNode.getAttributeValue("context"),
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/iq_sync_result.py 0000664 0000000 0000000 00000007632 13221545743 0030540 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .iq_sync import SyncIqProtocolEntity
class ResultSyncIqProtocolEntity(SyncIqProtocolEntity):
'''
{{number}}
abcdefgh
'''
def __init__(self,_id, sid, index, last, version, inNumbers, outNumbers, invalidNumbers, wait = None):
super(ResultSyncIqProtocolEntity, self).__init__("result", _id, sid, index, last)
self.setResultSyncProps(version, inNumbers, outNumbers, invalidNumbers, wait)
def setResultSyncProps(self, version, inNumbers, outNumbers, invalidNumbers, wait = None):
assert type(inNumbers) is dict, "in numbers must be a dict {number -> jid}"
assert type(outNumbers) is dict, "out numbers must be a dict {number -> jid}"
assert type(invalidNumbers) is list, "invalid numbers must be a list"
self.inNumbers = inNumbers
self.outNumbers = outNumbers
self.invalidNumbers = invalidNumbers
self.wait = int(wait) if wait is not None else None
self.version = version
def __str__(self):
out = super(SyncIqProtocolEntity, self).__str__()
if self.wait is not None:
out += "Wait: %s\n" % self.wait
out += "Version: %s\n" % self.version
out += "In Numbers: %s\n" % (",".join(self.inNumbers))
out += "Out Numbers: %s\n" % (",".join(self.outNumbers))
out += "Invalid Numbers: %s\n" % (",".join(self.invalidNumbers))
return out
def toProtocolTreeNode(self):
outUsers = [ProtocolTreeNode("user", {"jid": jid}, None, number) for number, jid in self.outNumbers.items()]
inUsers = [ProtocolTreeNode("user", {"jid": jid}, None, number) for number, jid in self.inNumbers.items()]
invalidUsers = [ProtocolTreeNode("user", {}, None, number) for number in self.invalidNumbers]
node = super(ResultSyncIqProtocolEntity, self).toProtocolTreeNode()
syncNode = node.getChild("sync")
syncNode.setAttribute("version", self.version)
if self.wait is not None:
syncNode.setAttribute("wait", str(self.wait))
if len(outUsers):
syncNode.addChild(ProtocolTreeNode("out", children = outUsers))
if len(inUsers):
syncNode.addChild(ProtocolTreeNode("in", children = inUsers))
if len(invalidUsers):
syncNode.addChildren([ProtocolTreeNode("invalid", children = invalidUsers)])
return node
@staticmethod
def fromProtocolTreeNode(node):
syncNode = node.getChild("sync")
outNode = syncNode.getChild("out")
inNode = syncNode.getChild("in")
invalidNode = syncNode.getChild("invalid")
outUsers = outNode.getAllChildren() if outNode else []
inUsers = inNode.getAllChildren() if inNode else []
invalidUsers = [inode.data for inode in invalidNode.getAllChildren()] if invalidNode else []
outUsersDict = {}
for u in outUsers:
outUsersDict[u.data] = u.getAttributeValue("jid")
inUsersDict = {}
for u in inUsers:
inUsersDict[u.data] = u.getAttributeValue("jid")
entity = SyncIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ResultSyncIqProtocolEntity
entity.setResultSyncProps(syncNode.getAttributeValue("version"),
inUsersDict,
outUsersDict,
invalidUsers,
syncNode.getAttributeValue("wait")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/notification_contact.py 0000664 0000000 0000000 00000001454 13221545743 0031672 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities import NotificationProtocolEntity
class ContactNotificationProtocolEntity(NotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, offline = False):
super(ContactNotificationProtocolEntity, self).__init__("contacts", _id, _from, timestamp, notify, offline)
@staticmethod
def fromProtocolTreeNode(node):
entity = NotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ContactNotificationProtocolEntity
return entity yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/notification_contact_add.py 0000664 0000000 0000000 00000002367 13221545743 0032506 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .notification_contact import ContactNotificationProtocolEntity
class AddContactNotificationProtocolEntity(ContactNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, offline, contactJid):
super(AddContactNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(contactJid)
def setData(self, jid):
self.contactJid = jid
def toProtocolTreeNode(self):
node = super(AddContactNotificationProtocolEntity, self).toProtocolTreeNode()
removeNode = ProtocolTreeNode("add", {"jid": self.contactJid}, None, None)
node.addChild(removeNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = ContactNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = AddContactNotificationProtocolEntity
removeNode = node.getChild("add")
entity.setData(removeNode.getAttributeValue("jid"))
return entity yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/notification_contact_remove.py 0000664 0000000 0000000 00000002417 13221545743 0033247 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .notification_contact import ContactNotificationProtocolEntity
class RemoveContactNotificationProtocolEntity(ContactNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, offline, contactJid):
super(RemoveContactNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(contactJid)
def setData(self, jid):
self.contactJid = jid
def toProtocolTreeNode(self):
node = super(RemoveContactNotificationProtocolEntity, self).toProtocolTreeNode()
removeNode = ProtocolTreeNode("remove", {"jid": self.contactJid}, None, None)
node.addChild(removeNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = ContactNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = RemoveContactNotificationProtocolEntity
removeNode = node.getChild("remove")
entity.setData(removeNode.getAttributeValue("jid"))
return entity yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/notification_contact_update.py 0000664 0000000 0000000 00000002417 13221545743 0033234 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .notification_contact import ContactNotificationProtocolEntity
class UpdateContactNotificationProtocolEntity(ContactNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, offline, contactJid):
super(UpdateContactNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(contactJid)
def setData(self, jid):
self.contactJid = jid
def toProtocolTreeNode(self):
node = super(UpdateContactNotificationProtocolEntity, self).toProtocolTreeNode()
removeNode = ProtocolTreeNode("update", {"jid": self.contactJid}, None, None)
node.addChild(removeNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = ContactNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = UpdateContactNotificationProtocolEntity
removeNode = node.getChild("update")
entity.setData(removeNode.getAttributeValue("jid"))
return entity yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/notificiation_contacts_sync.py 0000664 0000000 0000000 00000002325 13221545743 0033260 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .notification_contact import ContactNotificationProtocolEntity
class ContactsSyncNotificationProtocolEntity(ContactNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, offline, after):
super(ContactsSyncNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(after)
def setData(self, after):
self.after = int(after)
def toProtocolTreeNode(self):
node = super(ContactsSyncNotificationProtocolEntity, self).toProtocolTreeNode()
syncNode = ProtocolTreeNode("sync", {"after": str(self.after)}, None, None)
node.addChild(syncNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = ContactNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ContactsSyncNotificationProtocolEntity
syncNode = node.getChild("sync")
entity.setData(syncNode.getAttributeValue("after"))
return entity yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/test_iq_sync_get.py 0000664 0000000 0000000 00000000661 13221545743 0031033 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_contacts.protocolentities.iq_sync_get import GetSyncIqProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = GetSyncIqProtocolEntity(["12345678", "8764543121"])
class GetSyncIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = GetSyncIqProtocolEntity
self.node = entity.toProtocolTreeNode() yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/test_iq_sync_result.py 0000664 0000000 0000000 00000001370 13221545743 0031570 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_contacts.protocolentities.iq_sync_result import ResultSyncIqProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = ResultSyncIqProtocolEntity("123", "1.30615237617e+17", 0,
True, "123456", {"12345678": "12345678@s.whatsapp.net"},
{"12345678": "12345678@s.whatsapp.net"}, ["1234"])
class ResultSyncIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = ResultSyncIqProtocolEntity
self.node = entity.toProtocolTreeNode()
def test_delta_result(self):
del self.node.getChild("sync")["wait"]
self.test_generation()
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_add.py 0000664 0000000 0000000 00000001240 13221545743 0033532 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_contacts.protocolentities import AddContactNotificationProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import time
import unittest
entity = AddContactNotificationProtocolEntity("1234", "jid@s.whatsapp.net", int(time.time()), "notify", False,
"sender@s.whatsapp.net")
class AddContactNotificationProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
super(AddContactNotificationProtocolEntityTest, self).setUp()
self.ProtocolEntity = AddContactNotificationProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_remove.py 0000664 0000000 0000000 00000001145 13221545743 0034303 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_contacts.protocolentities import RemoveContactNotificationProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import time
import unittest
entity = RemoveContactNotificationProtocolEntity("1234", "jid@s.whatsapp.net",
int(time.time()), "notify", False, "contactjid@s.whatsapp.net")
class RemoveContactNotificationProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = RemoveContactNotificationProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_update.py 0000664 0000000 0000000 00000001144 13221545743 0034267 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_contacts.protocolentities import UpdateContactNotificationProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import time
import unittest
entity = UpdateContactNotificationProtocolEntity("1234", "jid@s.whatsapp.net",
int(time.time()), "notify", False,"contactjid@s.whatsapp.net")
class UpdateContactNotificationProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = UpdateContactNotificationProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_contacts/test_layer.py 0000664 0000000 0000000 00000002300 13221545743 0024225 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayerTest
from yowsup.layers.protocol_contacts import YowContactsIqProtocolLayer
from yowsup.layers.protocol_contacts.protocolentities.test_notification_contact_add import entity as addEntity
from yowsup.layers.protocol_contacts.protocolentities.test_notification_contact_update import entity as updateEntity
from yowsup.layers.protocol_contacts.protocolentities.test_notification_contact_remove import entity as removeEntity
from yowsup.layers.protocol_contacts.protocolentities.test_iq_sync_result import entity as syncResultEntity
from yowsup.layers.protocol_contacts.protocolentities.test_iq_sync_get import entity as syncGetEntity
class YowContactsIqProtocolLayerTest(YowProtocolLayerTest, YowContactsIqProtocolLayer):
def setUp(self):
YowContactsIqProtocolLayer.__init__(self)
def test_sync(self):
self.assertSent(syncGetEntity)
def test_syncResult(self):
self.assertReceived(syncResultEntity)
def test_notificationAdd(self):
self.assertReceived(addEntity)
def test_notificationUpdate(self):
self.assertReceived(updateEntity)
def test_notificationRemove(self):
self.assertReceived(removeEntity)
yowsup-2.5.7/yowsup/layers/protocol_groups/ 0000775 0000000 0000000 00000000000 13221545743 0021206 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_groups/__init__.py 0000664 0000000 0000000 00000000052 13221545743 0023314 0 ustar 00root root 0000000 0000000 from .layer import YowGroupsProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_groups/layer.py 0000664 0000000 0000000 00000015161 13221545743 0022700 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity
from yowsup.layers.protocol_iq.protocolentities.iq_result import ResultIqProtocolEntity
from .protocolentities import *
import logging
logger = logging.getLogger(__name__)
class YowGroupsProtocolLayer(YowProtocolLayer):
HANDLE = (
CreateGroupsIqProtocolEntity,
InfoGroupsIqProtocolEntity,
LeaveGroupsIqProtocolEntity,
ListGroupsIqProtocolEntity,
SubjectGroupsIqProtocolEntity,
ParticipantsGroupsIqProtocolEntity,
AddParticipantsIqProtocolEntity,
PromoteParticipantsIqProtocolEntity,
DemoteParticipantsIqProtocolEntity,
RemoveParticipantsIqProtocolEntity
)
def __init__(self):
handleMap = {
"iq": (None, self.sendIq),
"notification": (self.recvNotification, None)
}
super(YowGroupsProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Groups Iq Layer"
def sendIq(self, entity):
if entity.__class__ in self.__class__.HANDLE:
if entity.__class__ == SubjectGroupsIqProtocolEntity:
self._sendIq(entity, self.onSetSubjectSuccess, self.onSetSubjectFailed)
elif entity.__class__ == CreateGroupsIqProtocolEntity:
self._sendIq(entity, self.onCreateGroupSuccess, self.onCreateGroupFailed)
elif entity.__class__ == ParticipantsGroupsIqProtocolEntity:
self._sendIq(entity, self.onGetParticipantsResult)
elif entity.__class__ == AddParticipantsIqProtocolEntity:
self._sendIq(entity, self.onAddParticipantsSuccess, self.onAddParticipantsFailed)
elif entity.__class__ == PromoteParticipantsIqProtocolEntity:
self._sendIq(entity, self.onPromoteParticipantsSuccess, self.onPromoteParticipantsFailed)
elif entity.__class__ == DemoteParticipantsIqProtocolEntity:
self._sendIq(entity, self.onDemoteParticipantsSuccess, self.onDemoteParticipantsFailed)
elif entity.__class__ == RemoveParticipantsIqProtocolEntity:
self._sendIq(entity, self.onRemoveParticipantsSuccess, self.onRemoveParticipantsFailed)
elif entity.__class__ == ListGroupsIqProtocolEntity:
self._sendIq(entity, self.onListGroupsResult)
elif entity.__class__ == LeaveGroupsIqProtocolEntity:
self._sendIq(entity, self.onLeaveGroupSuccess, self.onLeaveGroupFailed)
elif entity.__class__ == InfoGroupsIqProtocolEntity:
self._sendIq(entity, self.onInfoGroupSuccess, self.onInfoGroupFailed)
else:
self.entityToLower(entity)
def onCreateGroupSuccess(self, node, originalIqEntity):
logger.info("Group create success")
self.toUpper(SuccessCreateGroupsIqProtocolEntity.fromProtocolTreeNode(node))
def onCreateGroupFailed(self, node, originalIqEntity):
logger.error("Group create failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onSetSubjectSuccess(self, node, originalIqEntity):
logger.info("Group subject change success")
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(node))
def onSetSubjectFailed(self, node, originalIqEntity):
logger.error("Group subject change failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onGetParticipantsResult(self, node, originalIqEntity):
self.toUpper(ListParticipantsResultIqProtocolEntity.fromProtocolTreeNode(node))
def onAddParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group add participants success")
self.toUpper(SuccessAddParticipantsIqProtocolEntity.fromProtocolTreeNode(node))
def onRemoveParticipantsFailed(self, node, originalIqEntity):
logger.error("Group remove participants failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onRemoveParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group remove participants success")
self.toUpper(SuccessRemoveParticipantsIqProtocolEntity.fromProtocolTreeNode(node))
def onPromoteParticipantsFailed(self, node, originalIqEntity):
logger.error("Group promote participants failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onPromoteParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group promote participants success")
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(node))
def onDemoteParticipantsFailed(self, node, originalIqEntity):
logger.error("Group demote participants failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onDemoteParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group demote participants success")
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(node))
def onAddParticipantsFailed(self, node, originalIqEntity):
logger.error("Group add participants failed")
self.toUpper(FailureAddParticipantsIqProtocolEntity.fromProtocolTreeNode(node))
def onListGroupsResult(self, node, originalIqEntity):
self.toUpper(ListGroupsResultIqProtocolEntity.fromProtocolTreeNode(node))
def onLeaveGroupSuccess(self, node, originalIqEntity):
logger.info("Group leave success")
self.toUpper(SuccessLeaveGroupsIqProtocolEntity.fromProtocolTreeNode(node))
def onLeaveGroupFailed(self, node, originalIqEntity):
logger.error("Group leave failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def onInfoGroupSuccess(self, node, originalIqEntity):
logger.info("Group info success")
self.toUpper(InfoGroupsResultIqProtocolEntity.fromProtocolTreeNode(node))
def onInfoGroupFailed(self, node, originalIqEntity):
logger.error("Group info failed")
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(node))
def recvNotification(self, node):
if node["type"] == "w:gp2":
if node.getChild("subject"):
self.toUpper(SubjectGroupsNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("create"):
self.toUpper(CreateGroupsNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("remove"):
self.toUpper(RemoveGroupsNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("add"):
self.toUpper(AddGroupsNotificationProtocolEntity.fromProtocolTreeNode(node))
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0024614 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/__init__.py 0000664 0000000 0000000 00000003252 13221545743 0026727 0 ustar 00root root 0000000 0000000 from .iq_groups_create import CreateGroupsIqProtocolEntity
from .iq_groups_create_success import SuccessCreateGroupsIqProtocolEntity
from .iq_groups_leave import LeaveGroupsIqProtocolEntity
from .iq_groups_leave_success import SuccessLeaveGroupsIqProtocolEntity
from .iq_groups_list import ListGroupsIqProtocolEntity
from .iq_groups_info import InfoGroupsIqProtocolEntity
from .iq_groups_subject import SubjectGroupsIqProtocolEntity
from .iq_groups_participants import ParticipantsGroupsIqProtocolEntity
from .iq_groups_participants_add import AddParticipantsIqProtocolEntity
from .iq_groups_participants_promote import PromoteParticipantsIqProtocolEntity
from .iq_groups_participants_demote import DemoteParticipantsIqProtocolEntity
from .iq_groups_participants_add_success import SuccessAddParticipantsIqProtocolEntity
from .iq_groups_participants_add_failure import FailureAddParticipantsIqProtocolEntity
from .iq_groups_participants_remove import RemoveParticipantsIqProtocolEntity
from .iq_groups_participants_remove_success import SuccessRemoveParticipantsIqProtocolEntity
from .iq_result_groups_list import ListGroupsResultIqProtocolEntity
from .iq_result_participants_list import ListParticipantsResultIqProtocolEntity
from .iq_result_groups_info import InfoGroupsResultIqProtocolEntity
from .notification_groups import GroupsNotificationProtocolEntity
from .notification_groups_subject import SubjectGroupsNotificationProtocolEntity
from .notification_groups_create import CreateGroupsNotificationProtocolEntity
from .notification_groups_add import AddGroupsNotificationProtocolEntity
from .notification_groups_remove import RemoveGroupsNotificationProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups.py 0000664 0000000 0000000 00000000707 13221545743 0027202 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
class GroupsIqProtocolEntity(IqProtocolEntity):
'''
'''
def __init__(self, to = None, _from = None, _id = None, _type = None):
super(GroupsIqProtocolEntity, self).__init__("w:g2", _id, _type, to = to, _from = _from)
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_create.py 0000664 0000000 0000000 00000003441 13221545743 0030523 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class CreateGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
'''
def __init__(self, subject, _id = None, participants = None):
super(CreateGroupsIqProtocolEntity, self).__init__(to = YowConstants.WHATSAPP_GROUP_SERVER, _id = _id, _type = "set")
self.setProps(subject)
self.setParticipants(participants or [])
def setProps(self, subject):
self.subject = subject
def setParticipants(self, participants):
self.participantList = participants
def toProtocolTreeNode(self):
node = super(CreateGroupsIqProtocolEntity, self).toProtocolTreeNode()
cnode = ProtocolTreeNode("create",{ "subject": self.subject})
participantNodes = [
ProtocolTreeNode("participant", {
"jid": participant
})
for participant in self.participantList
]
cnode.addChildren(participantNodes)
node.addChild(cnode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(CreateGroupsIqProtocolEntity,CreateGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = CreateGroupsIqProtocolEntity
entity.setProps(node.getChild("create").getAttributeValue("subject"))
participantList = []
for participantNode in node.getChild("create").getAllChildren():
participantList.append(participantNode["jid"])
entity.setParticipants(participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_create_success.py 0000664 0000000 0000000 00000002167 13221545743 0032257 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class SuccessCreateGroupsIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, _id, groupId):
super(SuccessCreateGroupsIqProtocolEntity, self).__init__(_from = YowConstants.WHATSAPP_GROUP_SERVER, _id = _id)
self.setProps(groupId)
def setProps(self, groupId):
self.groupId = groupId
def toProtocolTreeNode(self):
node = super(SuccessCreateGroupsIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("group",{"id": self.groupId}))
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SuccessCreateGroupsIqProtocolEntity, SuccessCreateGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SuccessCreateGroupsIqProtocolEntity
entity.setProps(node.getChild("group").getAttributeValue("id"))
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_info.py 0000664 0000000 0000000 00000002421 13221545743 0030210 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class InfoGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
'''
def __init__(self, group_jid, _id=None):
super(InfoGroupsIqProtocolEntity, self).__init__(to = group_jid, _id = _id, _type = "get")
self.setProps(group_jid)
def setProps(self, group_jid):
self.group_jid = group_jid
def __str__(self):
out = super(InfoGroupsIqProtocolEntity, self).__str__()
out += "Group JID: %s\n" % self.group_jid
return out
def toProtocolTreeNode(self):
node = super(InfoGroupsIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("query", {"request": "interactive"}))
return node
@staticmethod
def fromProtocolTreeNode(node):
assert node.getChild("query") is not None, "Not a groups info iq node %s" % node
entity = super(InfoGroupsIqProtocolEntity, InfoGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = InfoGroupsIqProtocolEntity
entity.setProps(node.getAttributeValue("to"))
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_leave.py 0000664 0000000 0000000 00000003317 13221545743 0030356 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class LeaveGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
'''
def __init__(self, groupList):
super(LeaveGroupsIqProtocolEntity, self).__init__(to = YowConstants.WHATSAPP_GROUP_SERVER, _type = "set")
self.setProps(groupList if type(groupList) is list else [groupList])
def setProps(self, groupList):
assert type(groupList) is list and len(groupList), "Must specify a list of group jids to leave"
self.groupList = groupList
def toProtocolTreeNode(self):
node = super(LeaveGroupsIqProtocolEntity, self).toProtocolTreeNode()
groupNodes = [
ProtocolTreeNode("group", {
"id": groupid
})
for groupid in self.groupList
]
node.addChild(ProtocolTreeNode("leave", {"action": "delete"}, groupNodes))
return node
@staticmethod
def fromProtocolTreeNode(node):
assert node.getChild("leave") is not None, "Not a group leave iq node %s" % node
assert node.getChild("leave").getAttributeValue("action") == "delete", "Not a group leave action %s" % node
entity = super(LeaveGroupsIqProtocolEntity, LeaveGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = LeaveGroupsIqProtocolEntity
entity.setProps([group.getAttributeValue("id") for group in node.getChild("leave").getAllChildren()] )
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_leave_success.py 0000664 0000000 0000000 00000002723 13221545743 0032106 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class SuccessLeaveGroupsIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, _id, groupId):
super(SuccessLeaveGroupsIqProtocolEntity, self).\
__init__(_from=YowConstants.WHATSAPP_GROUP_SERVER, _id=_id)
self.setProps(groupId)
def setProps(self, groupId):
self.groupId = groupId
def __str__(self):
out = super(SuccessLeaveGroupsIqProtocolEntity, self).__str__()
out += "Group Id: %s\n" % self.groupId
return out
def toProtocolTreeNode(self):
node = super(SuccessLeaveGroupsIqProtocolEntity, self).\
toProtocolTreeNode()
leaveNode = ProtocolTreeNode(
"leave", {}, [ProtocolTreeNode("group", {"id": self.groupId})]
)
node.addChild(leaveNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SuccessLeaveGroupsIqProtocolEntity, SuccessLeaveGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SuccessLeaveGroupsIqProtocolEntity
entity.setProps(
node.getChild("leave").getChild("group").getAttributeValue("id")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_list.py 0000664 0000000 0000000 00000004207 13221545743 0030234 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class ListGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
<"{{participating | owning}}">"{{participating | owning}}">
result (processed in iq_result_groups_list.py):
'''
GROUP_TYPE_PARTICIPATING = "participating"
GROUP_TYPE_OWNING = "owning"
GROUPS_TYPES = (GROUP_TYPE_PARTICIPATING, GROUP_TYPE_OWNING)
def __init__(self, groupsType = GROUP_TYPE_PARTICIPATING, _id = None):
super(ListGroupsIqProtocolEntity, self).__init__(_id=_id, to = YowConstants.WHATSAPP_GROUP_SERVER, _type = "get")
self.setProps(groupsType)
def setProps(self, groupsType):
assert groupsType in self.__class__.GROUPS_TYPES,\
"Groups type must be %s, not %s" % (" or ".join(self.__class__.GROUPS_TYPES), groupsType)
self.groupsType = groupsType
def toProtocolTreeNode(self):
node = super(ListGroupsIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode(self.groupsType))
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(ListGroupsIqProtocolEntity, ListGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = ListGroupsIqProtocolEntity
entity.setProps(node.getChild(0).tag)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants.py 0000664 0000000 0000000 00000003151 13221545743 0031757 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class ParticipantsGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
'''
modes=["add","promote","remove","demote"]
def __init__(self, jid, participantList, _mode, _id = None):
super(ParticipantsGroupsIqProtocolEntity, self).__init__(to = jid, _id = _id, _type = "set")
self.setProps(group_jid = jid, participantList = participantList, mode = _mode)
def setProps(self, group_jid, participantList, mode):
assert type(participantList) is list, "Must be a list of jids, got %s instead." % type(participantList)
assert mode in self.modes, "Mode should be in: '" + "', '".join(self.modes) + "' but is '" + mode + "'"
self.group_jid = group_jid
self.participantList = participantList
self.mode = mode
def toProtocolTreeNode(self):
node = super(ParticipantsGroupsIqProtocolEntity, self).toProtocolTreeNode()
participantNodes = [
ProtocolTreeNode("participant", {
"jid": participant
})
for participant in self.participantList
]
node.addChild(ProtocolTreeNode(self.mode,{}, participantNodes))
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(ParticipantsGroupsIqProtocolEntity, ParticipantsGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = ParticipantsGroupsIqProtocolEntity
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add.py 0000664 0000000 0000000 00000002101 13221545743 0032561 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups_participants import ParticipantsGroupsIqProtocolEntity
class AddParticipantsIqProtocolEntity(ParticipantsGroupsIqProtocolEntity):
'''
'''
def __init__(self, group_jid, participantList, _id = None):
super(AddParticipantsIqProtocolEntity, self).__init__(group_jid, participantList, "add", _id = _id)
@staticmethod
def fromProtocolTreeNode(node):
entity = super(AddParticipantsIqProtocolEntity, AddParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = AddParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getChild("add").getAllChildren():
participantList.append(participantNode["jid"])
entity.setProps(node.getAttributeValue("to"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add_failure.py 0000664 0000000 0000000 00000001516 13221545743 0034301 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity
class FailureAddParticipantsIqProtocolEntity(ErrorIqProtocolEntity):
'''
'''
def __init__(self, _id, _from, _code, _text, _backoff= 0 ):
super(FailureAddParticipantsIqProtocolEntity, self).__init__(_from = _from,
_id = _id, code = _code,
text = _text, backoff = _backoff)
@staticmethod
def fromProtocolTreeNode(node):
entity = ErrorIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = FailureAddParticipantsIqProtocolEntity
return entity yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add_success.py 0000664 0000000 0000000 00000003371 13221545743 0034323 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class SuccessAddParticipantsIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, _id, groupId, participantList):
super(SuccessAddParticipantsIqProtocolEntity, self).__init__(_from = groupId, _id = _id)
self.setProps(groupId, participantList)
def setProps(self, groupId, participantList):
self.groupId = groupId
self.participantList = participantList
self.action = 'add'
def getAction(self):
return self.action
def toProtocolTreeNode(self):
node = super(SuccessAddParticipantsIqProtocolEntity, self).toProtocolTreeNode()
participantNodes = [
ProtocolTreeNode("add", {
"type": "success",
"participant": participant
})
for participant in self.participantList
]
node.addChildren(participantNodes)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SuccessAddParticipantsIqProtocolEntity, SuccessAddParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SuccessAddParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getAllChildren():
if participantNode["type"]=="success":
participantList.append(participantNode["participant"])
entity.setProps(node.getAttributeValue("from"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_demote.py 0000664 0000000 0000000 00000002141 13221545743 0033312 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups_participants import ParticipantsGroupsIqProtocolEntity
class DemoteParticipantsIqProtocolEntity(ParticipantsGroupsIqProtocolEntity):
'''
'''
def __init__(self, group_jid, participantList, _id = None):
super(DemoteParticipantsIqProtocolEntity, self).__init__(group_jid, participantList, "demote", _id = _id)
@staticmethod
def fromProtocolTreeNode(node):
entity = super(DemoteParticipantsIqProtocolEntity, DemoteParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = DemoteParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getChild("demote").getAllChildren():
participantList.append(participantNode["jid"])
entity.setProps(node.getAttributeValue("to"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_promote.py 0000664 0000000 0000000 00000002152 13221545743 0033524 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups_participants import ParticipantsGroupsIqProtocolEntity
class PromoteParticipantsIqProtocolEntity(ParticipantsGroupsIqProtocolEntity):
'''
'''
def __init__(self, group_jid, participantList, _id = None):
super(PromoteParticipantsIqProtocolEntity, self).__init__(group_jid, participantList, "promote", _id = _id)
@staticmethod
def fromProtocolTreeNode(node):
entity = super(PromoteParticipantsIqProtocolEntity, PromoteParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = PromoteParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getChild("promote").getAllChildren():
participantList.append(participantNode["jid"])
entity.setProps(node.getAttributeValue("to"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_remove.py 0000664 0000000 0000000 00000002150 13221545743 0033332 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups_participants import ParticipantsGroupsIqProtocolEntity
class RemoveParticipantsIqProtocolEntity(ParticipantsGroupsIqProtocolEntity):
'''
'''
def __init__(self, group_jid, participantList, _id = None):
super(RemoveParticipantsIqProtocolEntity, self).__init__(group_jid, participantList, "remove", _id = _id)
@staticmethod
def fromProtocolTreeNode(node):
entity = super(RemoveParticipantsIqProtocolEntity, RemoveParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = RemoveParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getChild("remove").getAllChildren():
participantList.append(participantNode["jid"])
entity.setProps(node.getAttributeValue("to"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_remove_success.py0000664 0000000 0000000 00000003435 13221545743 0035071 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class SuccessRemoveParticipantsIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, _id, groupId, participantList):
super(SuccessRemoveParticipantsIqProtocolEntity, self).__init__(_from = groupId, _id = _id)
self.setProps(groupId, participantList)
def setProps(self, groupId, participantList):
self.groupId = groupId
self.participantList = participantList
self.action = 'remove'
def getAction(self):
return self.action
def toProtocolTreeNode(self):
node = super(SuccessRemoveParticipantsIqProtocolEntity, self).toProtocolTreeNode()
participantNodes = [
ProtocolTreeNode("remove", {
"type": "success",
"participant": participant
})
for participant in self.participantList
]
node.addChildren(participantNodes)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SuccessRemoveParticipantsIqProtocolEntity, SuccessRemoveParticipantsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SuccessRemoveParticipantsIqProtocolEntity
participantList = []
for participantNode in node.getAllChildren():
if participantNode["type"]=="success":
participantList.append(participantNode["participant"])
entity.setProps(node.getAttributeValue("from"), participantList)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_groups_subject.py 0000664 0000000 0000000 00000002064 13221545743 0030717 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class SubjectGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
{{NEW_VAL}}
'''
def __init__(self, jid, subject, _id = None):
super(SubjectGroupsIqProtocolEntity, self).__init__(to = jid, _id = _id, _type = "set")
self.setProps(subject)
def setProps(self, subject):
self.subject = subject
def toProtocolTreeNode(self):
node = super(SubjectGroupsIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("subject",{}, None, self.subject))
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SubjectGroupsIqProtocolEntity, SubjectGroupsIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SubjectGroupsIqProtocolEntity
entity.setProps(node.getChild("subject").getData())
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_result_groups_info.py 0000664 0000000 0000000 00000010240 13221545743 0031604 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class InfoGroupsResultIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
TYPE_PARTICIPANT_ADMIN = "admin"
def __init__(self, _id, _from,
groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid,
participants):
super(InfoGroupsResultIqProtocolEntity, self).__init__(_id = _id, _from = _from)
self.setGroupProps(groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid, participants)
def setGroupProps(self, groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid,
participants):
assert type(participants) is dict, "Participants must be a dict {jid => type?}"
self.groupId = groupId
self.creationTimestamp = int(creationTimestamp)
self.creatorJid = creatorJid
self.subject = subject
self.subjectTime = int(subjectTime)
self.subjectOwnerJid = subjectOwnerJid
self.participants = participants
def getParticipants(self):
return self.participants
def getSubject(self):
return self.subject
def getGroupId(self):
return self.groupId
def getCreationTimestamp(self):
return self.creationTimestamp
def getCreatorJid(self, full = True):
return self.creatorJid if full else self.creatorJid.split('@')[0]
def getSubjectTimestamp(self):
return self.subjectTime
def getSubjectOwnerJid(self, full = True):
return self.subjectOwnerJid if full else self.subjectOwnerJid.split('@')[0]
def getGroupAdmins(self, full = True):
admins = []
for jid, _type in self.participants.items():
if _type == self.__class__.TYPE_PARTICIPANT_ADMIN:
admins.append(jid if full else jid.split('@')[0])
return admins
def __str__(self):
out = super(InfoGroupsResultIqProtocolEntity, self).__str__()
out += "Group ID: %s\n" % self.groupId
out += "Created: %s\n" % self.creationTimestamp
out += "Creator JID: %s\n" % self.creatorJid
out += "Subject: %s\n" % self.subject
out += "Subject Timestamp: %s\n" % self.subjectTime
out += "Subject owner JID: %s\n" % self.subjectOwnerJid
out += "Participants: %s\n" % self.participants
return out
def toProtocolTreeNode(self):
node = super(InfoGroupsResultIqProtocolEntity, self).toProtocolTreeNode()
groupNode = ProtocolTreeNode("group", {
"subject": self.getSubject(),
"creation": str(self.getCreationTimestamp()),
"creator": self.getCreatorJid(),
"s_t": self.getSubjectTimestamp(),
"s_o": self.getSubjectOwnerJid(),
"id": self.getGroupId()
})
participants = []
for jid, _type in self.getParticipants().items():
pnode = ProtocolTreeNode("participant", {"jid": jid})
if _type:
pnode["type"] = _type
participants.append(pnode)
groupNode.addChildren(participants)
node.addChild(groupNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
groupNode = node.getChild("group")
participants = {}
for p in groupNode.getAllChildren("participant"):
participants[p["jid"]] = p["type"]
return InfoGroupsResultIqProtocolEntity(
node["id"], node["from"],
groupNode["id"], groupNode["creation"], groupNode["creator"], groupNode["subject"],
groupNode["s_t"], groupNode["s_o"], participants
)
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_result_groups_list.py 0000664 0000000 0000000 00000006475 13221545743 0031643 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
from ..structs import Group
class ListGroupsResultIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, groupsList):
super(ListGroupsResultIqProtocolEntity, self).__init__(_from = YowConstants.WHATSAPP_GROUP_SERVER)
self.setProps(groupsList)
def __str__(self):
out = super(ListGroupsResultIqProtocolEntity, self).__str__()
out += "Groups:\n"
for g in self.groupsList:
out += "%s\n" % g
return out
def getGroups(self):
return self.groupsList
def setProps(self, groupsList):
assert type(groupsList) is list and (len(groupsList) == 0 or groupsList[0].__class__ is Group),\
"groupList must be a list of Group instances"
self.groupsList = groupsList
def toProtocolTreeNode(self):
node = super(ListGroupsResultIqProtocolEntity, self).toProtocolTreeNode()
groupsNodes = []
for group in self.groupsList:
groupNode = ProtocolTreeNode("group", {
"id": group.getId(),
"creator": group.getCreator(),
"subject": group.getSubject(),
"s_o": group.getSubjectOwner(),
"s_t": str(group.getSubjectTime()),
"creation": str(group.getCreationTime())
},
)
participants = []
for jid, _type in group.getParticipants().items():
pnode = ProtocolTreeNode("participant", {"jid": jid})
if _type:
pnode["type"] = _type
participants.append(pnode)
groupNode.addChildren(participants)
groupsNodes.append(groupNode)
node.addChild(ProtocolTreeNode("groups", children = groupsNodes))
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(ListGroupsResultIqProtocolEntity, ListGroupsResultIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = ListGroupsResultIqProtocolEntity
groups = []
for groupNode in node.getChild("groups").getAllChildren():
participants = {}
for p in groupNode.getAllChildren("participant"):
participants[p["jid"]] = p["type"]
groups.append(
Group(groupNode["id"], groupNode["creator"], groupNode["subject"], groupNode["s_o"], groupNode["s_t"], groupNode["creation"], participants)
)
entity.setProps(groups)
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/iq_result_participants_list.py 0000664 0000000 0000000 00000003134 13221545743 0033012 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
class ListParticipantsResultIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, _from, participantList):
super(ListParticipantsResultIqProtocolEntity, self).__init__(_from = _from)
self.setParticipants(participantList)
def __str__(self):
out = super(ListParticipantsResultIqProtocolEntity, self).__str__()
out += "Participants: %s\n" % " ".join(self.participantList)
return out
def getParticipants(self):
return self.participantList
def setParticipants(self, participants):
self.participantList = participants
def toProtocolTreeNode(self):
node = super(ListParticipantsResultIqProtocolEntity, self).toProtocolTreeNode()
participantNodes = [
ProtocolTreeNode("participant", {
"jid": participant
})
for participant in self.participantList
]
node.addChildren(participantNodes)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(ListParticipantsResultIqProtocolEntity, ListParticipantsResultIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = ListParticipantsResultIqProtocolEntity
entity.setParticipants([ pNode.getAttributeValue("jid") for pNode in node.getAllChildren() ])
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/notification_groups.py 0000664 0000000 0000000 00000003314 13221545743 0031254 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities import NotificationProtocolEntity
class GroupsNotificationProtocolEntity(NotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, participant, offline):
super(GroupsNotificationProtocolEntity, self).__init__("w:gp2", _id, _from, timestamp, notify, offline)
self.setParticipant(participant)
self.setGroupId(_from)
def setParticipant(self, participant):
self._participant = participant
def getParticipant(self, full = True):
return self._participant if full else self._participant.split('@')[0]
def getGroupId(self):
return self.groupId
def setGroupId(self, groupId):
self.groupId = groupId
def __str__(self):
out = super(GroupsNotificationProtocolEntity, self).__str__()
out += "Participant: %s\n" % self.getParticipant()
return out
def toProtocolTreeNode(self):
node = super(GroupsNotificationProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("participant", self.getParticipant())
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(GroupsNotificationProtocolEntity, GroupsNotificationProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = GroupsNotificationProtocolEntity
entity.setParticipant(node.getAttributeValue("participant"))
entity.setGroupId(node.getAttributeValue("from"))
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/notification_groups_add.py 0000664 0000000 0000000 00000003632 13221545743 0032067 0 ustar 00root root 0000000 0000000 from .notification_groups import GroupsNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
class AddGroupsNotificationProtocolEntity(GroupsNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, timestamp, notify, participant, offline, participants):
super(AddGroupsNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, participant, offline)
self.setParticipants(participants)
def setParticipants(self, participants):
assert type(participants) is list, "Must be a list of jids, got %s instead." % type(participants)
self.participants = participants
def getParticipants(self):
return self.participants
def __str__(self):
out = super(AddGroupsNotificationProtocolEntity, self).__str__()
out += "Participants: %s\n" % " ".join(self.getParticipants())
return out
def toProtocolTreeNode(self):
node = super(AddGroupsNotificationProtocolEntity, self).toProtocolTreeNode()
addNode = ProtocolTreeNode("add")
participants = []
for jid in self.getParticipants():
pnode = ProtocolTreeNode("participant", {"jid": jid})
participants.append(pnode)
addNode.addChildren(participants)
node.addChild(addNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
addNode = node.getChild("add")
participants = []
for p in addNode.getAllChildren("participant"):
participants.append(p["jid"])
return AddGroupsNotificationProtocolEntity(
node["id"], node["from"], node["t"], node["notify"], node["participant"], node["offline"],
participants
) yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/notification_groups_create.py 0000664 0000000 0000000 00000011263 13221545743 0032601 0 ustar 00root root 0000000 0000000 from .notification_groups import GroupsNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
class CreateGroupsNotificationProtocolEntity(GroupsNotificationProtocolEntity):
'''
'''
TYPE_CREATE_NEW = "new"
TYPE_PARTICIPANT_ADMIN = "admin"
def __init__(self, _id, _from, timestamp, notify, participant, offline,
createType, groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid,
participants):
super(CreateGroupsNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, participant, offline)
self.setGroupProps(createType, groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid, participants)
def setGroupProps(self, createType, groupId, creationTimestamp, creatorJid,
subject, subjectTime, subjectOwnerJid,
participants):
assert type(participants) is dict, "Participants must be a dict {jid => type?}"
self.createType = createType
self.groupId = groupId
self.creationTimestamp = int(creationTimestamp)
self.creatorJid = creatorJid
self.subject = subject
self.subjectTime = int(subjectTime)
self.subjectOwnerJid = subjectOwnerJid
self.participants = participants
def getParticipants(self):
return self.participants
def getSubject(self):
return self.subject
def getGroupId(self):
return self.groupId
def getCreationTimestamp(self):
return self.creationTimestamp
def getCreatorJid(self, full = True):
return self.creatorJid if full else self.creatorJid.split('@')[0]
def getSubjectTimestamp(self):
return self.subjectTime
def getSubjectOwnerJid(self, full = True):
return self.subjectOwnerJid if full else self.subjectOwnerJid.split('@')[0]
def getCreatetype(self):
return self.createType
def getGroupAdmin(self, full = True):
for jid, _type in self.participants.items():
if _type == self.__class__.TYPE_PARTICIPANT_ADMIN:
return jid if full else jid.split('@')[0]
def __str__(self):
out = super(CreateGroupsNotificationProtocolEntity, self).__str__()
out += "Creator: %s\n" % self.getCreatorJid()
out += "Create type: %s\n" % self.getCreatetype()
out += "Creation timestamp: %s\n" % self.getCreationTimestamp()
out += "Subject: %s\n" % self.getSubject()
out += "Subject owner: %s\n" % self.getSubjectOwnerJid()
out += "Subject timestamp: %s\n" % self.getSubjectTimestamp()
out += "Participants: %s\n" % self.getParticipants()
return out
def toProtocolTreeNode(self):
node = super(CreateGroupsNotificationProtocolEntity, self).toProtocolTreeNode()
createNode = ProtocolTreeNode("create", {"type": self.getCreatetype()})
groupNode = ProtocolTreeNode("group", {
"subject": self.getSubject(),
"creation": str(self.getCreationTimestamp()),
"creator": self.getCreatorJid(),
"s_t": self.getSubjectTimestamp(),
"s_o": self.getSubjectOwnerJid(),
"id": self.getGroupId()
})
participants = []
for jid, _type in self.getParticipants().items():
pnode = ProtocolTreeNode("participant", {"jid": jid})
if _type:
pnode["type"] = _type
participants.append(pnode)
groupNode.addChildren(participants)
createNode.addChild(groupNode)
node.addChild(createNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
createNode = node.getChild("create")
groupNode = createNode.getChild("group")
participants = {}
for p in groupNode.getAllChildren("participant"):
participants[p["jid"]] = p["type"]
return CreateGroupsNotificationProtocolEntity(
node["id"], node["from"], node["t"], node["notify"], node["participant"], node["offline"],
createNode["type"], groupNode["id"], groupNode["creation"], groupNode["creator"], groupNode["subject"],
groupNode["s_t"], groupNode["s_o"], participants
)
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/notification_groups_remove.py 0000664 0000000 0000000 00000004116 13221545743 0032632 0 ustar 00root root 0000000 0000000 from .notification_groups import GroupsNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
class RemoveGroupsNotificationProtocolEntity(GroupsNotificationProtocolEntity):
'''
'''
TYPE_PARTICIPANT_ADMIN = "admin"
def __init__(self, _id, _from, timestamp, notify, participant, offline,
subject,
participants):
super(RemoveGroupsNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, participant, offline)
self.setGroupProps(subject, participants)
def setGroupProps(self,
subject,
participants):
assert type(participants) is list, "Must be a list of jids, got %s instead." % type(participants)
self.subject = subject
self.participants = participants
def getParticipants(self):
return self.participants
def getSubject(self):
return self.subject
def toProtocolTreeNode(self):
node = super(RemoveGroupsNotificationProtocolEntity, self).toProtocolTreeNode()
removeNode = ProtocolTreeNode("remove", {"subject": self.subject})
participants = []
for jid in self.getParticipants():
pnode = ProtocolTreeNode("participant", {"jid": jid})
participants.append(pnode)
removeNode.addChildren(participants)
node.addChild(removeNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
removeNode = node.getChild("remove")
participants = []
for p in removeNode.getAllChildren("participant"):
participants.append(p["jid"])
return RemoveGroupsNotificationProtocolEntity(
node["id"], node["from"], node["t"], node["notify"], node["participant"], node["offline"],
removeNode["subject"], participants
)
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/notification_groups_subject.py 0000664 0000000 0000000 00000004400 13221545743 0032770 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities import NotificationProtocolEntity
from .notification_groups import GroupsNotificationProtocolEntity
class SubjectGroupsNotificationProtocolEntity(GroupsNotificationProtocolEntity):
'''
'''
def __init__(self, _type, _id, _from, timestamp, notify, participant, subject):
super(SubjectGroupsNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, participant)
self.setSubjectData(subject)
def setSubjectData(self, subject, subjectOwner, subjectTimestamp):
self.subject = subject
self.subjectOwner = subjectOwner
self.subjectTimestamp = int(subjectTimestamp)
def getSubject(self):
return self.subject
def getSubjectOwner(self, full = True):
return self.subjectOwner if full else self.subjectOwner.split('@')[0]
def getSubjectTimestamp(self):
return self.subjectTimestamp
def __str__(self):
out = super(SubjectGroupsNotificationProtocolEntity, self).__str__()
out += "New subject: %s\n" % self.getSubject()
out += "Set by: %s\n" % self.getSubjectOwner()
return out
def toProtocolTreeNode(self):
node = super(SubjectGroupsNotificationProtocolEntity, self).toProtocolTreeNode()
subjectNode = ProtocolTreeNode("subject", {
"s_t": str(self.getSubjectTimestamp()),
"s_o": self.getSubjectOwner(),
"subject": self.getSubject()
})
node.addChild(subjectNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(SubjectGroupsNotificationProtocolEntity, SubjectGroupsNotificationProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = SubjectGroupsNotificationProtocolEntity
subjectNode = node.getChild("subject")
entity.setSubjectData(subjectNode["subject"], subjectNode["s_o"], subjectNode["s_t"])
return entity
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_groups.py 0000664 0000000 0000000 00000000226 13221545743 0030235 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
class GroupsIqProtocolEntityTest(IqProtocolEntityTest):
pass
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_create.py 0000664 0000000 0000000 00000000676 13221545743 0031571 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_groups.protocolentities.iq_groups_create import CreateGroupsIqProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = CreateGroupsIqProtocolEntity("group subject")
class CreateGroupsIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = CreateGroupsIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_create_success.py 0000664 0000000 0000000 00000000716 13221545743 0033314 0 ustar 00root root 0000000 0000000 from yowsup.structs.protocolentity import ProtocolEntityTest
from yowsup.layers.protocol_groups.protocolentities import SuccessCreateGroupsIqProtocolEntity
import unittest
entity = SuccessCreateGroupsIqProtocolEntity("123-456", "431-123")
class SuccessCreateGroupsIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = SuccessCreateGroupsIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_list.py 0000664 0000000 0000000 00000000645 13221545743 0031275 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_groups.protocolentities.iq_groups_list import ListGroupsIqProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
entity = ListGroupsIqProtocolEntity()
class ListGroupsIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = ListGroupsIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_result_groups.py 0000664 0000000 0000000 00000000256 13221545743 0031636 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq_result import ResultIqProtocolEntityTest
class GroupsResultIqProtocolEntityTest(ResultIqProtocolEntityTest):
pass yowsup-2.5.7/yowsup/layers/protocol_groups/protocolentities/test_iq_result_groups_list.py 0000664 0000000 0000000 00000001420 13221545743 0032663 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_groups.protocolentities.iq_result_groups_list import ListGroupsResultIqProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
from yowsup.layers.protocol_groups.structs import Group
import unittest
import time
entity = ListGroupsResultIqProtocolEntity(
[
Group("1234-456", "owner@s.whatsapp.net", "subject", "sOwnerJid@s.whatsapp.net", int(time.time()), int(time.time())),
Group("4321-456", "owner@s.whatsapp.net", "subject", "sOwnerJid@s.whatsapp.net", int(time.time()), int(time.time()))
]
)
class ListGroupsResultIqProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = ListGroupsResultIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_groups/structs/ 0000775 0000000 0000000 00000000000 13221545743 0022715 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_groups/structs/__init__.py 0000664 0000000 0000000 00000000030 13221545743 0025017 0 ustar 00root root 0000000 0000000 from .group import Group yowsup-2.5.7/yowsup/layers/protocol_groups/structs/group.py 0000664 0000000 0000000 00000002407 13221545743 0024426 0 ustar 00root root 0000000 0000000 class Group(object):
def __init__(self, groupId, creatorJid, subject, subjectOwnerJid, subjectTime, creationTime, participants=None):
self._groupId = groupId
self._creatorJid = creatorJid
self._subject = subject
self._subjectOwnerJid = subjectOwnerJid
self._subjectTime = int(subjectTime)
self._creationTime = int(creationTime)
self._participants = participants or {}
def getId(self):
return self._groupId
def getCreator(self):
return self._creatorJid
def getOwner(self):
return self.getCreator()
def getSubject(self):
return self._subject
def getSubjectOwner(self):
return self._subjectOwnerJid
def getSubjectTime(self):
return self._subjectTime
def getCreationTime(self):
return self._creationTime
def __str__(self):
return "ID: %s, Subject: %s, Creation: %s, Creator: %s, Subject Owner: %s, Subject Time: %s\nParticipants: %s" %\
(self.getId(), self.getSubject(), self.getCreationTime(), self.getCreator(), self.getSubjectOwner(), self.getSubjectTime(), ", ".join(self._participants.keys()))
def getParticipants(self):
return self._participants
yowsup-2.5.7/yowsup/layers/protocol_ib/ 0000775 0000000 0000000 00000000000 13221545743 0020261 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_ib/__init__.py 0000664 0000000 0000000 00000000047 13221545743 0022373 0 ustar 00root root 0000000 0000000 from .layer import YowIbProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_ib/layer.py 0000664 0000000 0000000 00000001721 13221545743 0021750 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
class YowIbProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"ib": (self.recvIb, self.sendIb),
"iq": (None, self.sendIb)
}
super(YowIbProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Ib Layer"
def sendIb(self, entity):
if entity.__class__ == CleanIqProtocolEntity:
self.toLower(entity.toProtocolTreeNode())
def recvIb(self, node):
if node.getChild("dirty"):
self.toUpper(DirtyIbProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("offline"):
self.toUpper(OfflineIbProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("account"):
self.toUpper(AccountIbProtocolEntity.fromProtocolTreeNode(node))
else:
raise ValueError("Unkown ib node %s" % node)
yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0023667 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/__init__.py 0000664 0000000 0000000 00000000267 13221545743 0026005 0 ustar 00root root 0000000 0000000 from .clean_iq import CleanIqProtocolEntity
from .dirty_ib import DirtyIbProtocolEntity
from .offline_ib import OfflineIbProtocolEntity
from .account_ib import AccountIbProtocolEntity yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/account_ib.py 0000664 0000000 0000000 00000003714 13221545743 0026354 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .ib import IbProtocolEntity
class AccountIbProtocolEntity(IbProtocolEntity):
'''
'''
STATUS_ACTIVE = "active"
KIND_PAD = "paid"
def __init__(self, status, kind, creation, expiration):
super(AccountIbProtocolEntity, self).__init__()
self.setProps(status, kind, creation, expiration)
def setProps(self, status, kind, creation, expiration):
self.status = status
self.creation = int(creation)
self.kind = kind
self.expiration= int(expiration)
def toProtocolTreeNode(self):
node = super(AccountIbProtocolEntity, self).toProtocolTreeNode()
accountChild = ProtocolTreeNode("account",
{
"status": self.status,
"kind": self.kind,
"creation": int(self.creation),
"expiration": int(self.expiration)
})
node.addChild(accountChild)
return node
def __str__(self):
out = super(AccountIbProtocolEntity, self).__str__()
out += "Status: %s\n" % self.status
out += "Kind: %s\n" % self.kind
out += "Creation: %s\n" % self.creation
out += "Expiration: %s\n" % self.expiration
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = IbProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = AccountIbProtocolEntity
accountNode = node.getChild("account")
entity.setProps(
accountNode["status"],
accountNode["kind"],
accountNode["creation"],
accountNode["expiration"]
) yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/clean_iq.py 0000664 0000000 0000000 00000002421 13221545743 0026013 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
class CleanIqProtocolEntity(IqProtocolEntity):
'''
'''
def __init__(self, cleanType, to, _id = None):
super(CleanIqProtocolEntity, self).__init__(
"urn:xmpp:whatsapp:dirty",
_id = _id,
_type = "set",
to = to
)
self.setProps(cleanType)
def setProps(self, cleanType):
self.cleanType = cleanType
def __str__(self):
out = super(CleanIqProtocolEntity, self).__str__()
out += "Clean Type: %s\n" % self.cleanType
return out
def toProtocolTreeNode(self):
node = super(CleanIqProtocolEntity, self).toProtocolTreeNode()
cleanNode = ProtocolTreeNode("clean", {"type": self.cleanType})
node.addChild(cleanNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = CleanIqProtocolEntity
entity.setProps(node.getChild("clean").getAttributeValue("type"))
return entity yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/dirty_ib.py 0000664 0000000 0000000 00000002401 13221545743 0026043 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .ib import IbProtocolEntity
class DirtyIbProtocolEntity(IbProtocolEntity):
'''
'''
def __init__(self, timestamp, _type):
super(DirtyIbProtocolEntity, self).__init__()
self.setProps(timestamp, _type)
def setProps(self, timestamp, _type):
self.timestamp = int(timestamp)
self._type = _type
def toProtocolTreeNode(self):
node = super(DirtyIbProtocolEntity, self).toProtocolTreeNode()
dirtyNode = ProtocolTreeNode("dirty")
dirtyNode["timestamp"] = str(self.timestamp)
dirtyNode["type"] = self._type
node.addChild(dirtyNode)
return node
def __str__(self):
out = super(DirtyIbProtocolEntity, self).__str__()
out += "Type: %s\n" % self._type
out += "Timestamp: %s\n" % self.timestamp
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = IbProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = DirtyIbProtocolEntity
dirtyChild = node.getChild("dirty")
entity.setProps(dirtyChild["timestamp"], dirtyChild["type"])
return entity
yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/ib.py 0000664 0000000 0000000 00000000715 13221545743 0024636 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class IbProtocolEntity(ProtocolEntity):
'''
'''
def __init__(self):
super(IbProtocolEntity, self).__init__("ib")
def toProtocolTreeNode(self):
return self._createProtocolTreeNode({}, None, None)
def __str__(self):
out = "Ib:\n"
return out
@staticmethod
def fromProtocolTreeNode(node):
return IbProtocolEntity()
yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/offline_ib.py 0000664 0000000 0000000 00000002050 13221545743 0026332 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .ib import IbProtocolEntity
class OfflineIbProtocolEntity(IbProtocolEntity):
'''
'''
def __init__(self, count):
super(IbProtocolEntity, self).__init__()
self.setProps(count)
def setProps(self, count):
self.count = int(count)
def toProtocolTreeNode(self):
node = super(OfflineIbProtocolEntity, self).toProtocolTreeNode()
offlineChild = ProtocolTreeNode("offline", {"count": str(self.count)})
node.addChild(offlineChild)
return node
def __str__(self):
out = super(OfflineIbProtocolEntity, self).__str__()
out += "Offline count: %s\n" % self.count
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = IbProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = OfflineIbProtocolEntity
entity.setProps(node.getChild("offline")["count"])
return entity
yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/test_clean_iq.py 0000664 0000000 0000000 00000000765 13221545743 0027063 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_ib.protocolentities.clean_iq import CleanIqProtocolEntity
from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
class CleanIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(CleanIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = CleanIqProtocolEntity
cleanNode = ProtocolTreeNode("clean", {"type": "groups"})
self.node.addChild(cleanNode) yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/test_dirty_ib.py 0000664 0000000 0000000 00000001057 13221545743 0027110 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_ib.protocolentities.test_ib import IbProtocolEntityTest
from yowsup.layers.protocol_ib.protocolentities.dirty_ib import DirtyIbProtocolEntity
from yowsup.structs import ProtocolTreeNode
class DirtyIbProtocolEntityTest(IbProtocolEntityTest):
def setUp(self):
super(DirtyIbProtocolEntityTest, self).setUp()
self.ProtocolEntity = DirtyIbProtocolEntity
dirtyNode = ProtocolTreeNode("dirty")
dirtyNode["timestamp"] = "123456"
dirtyNode["type"] = "groups"
self.node.addChild(dirtyNode) yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/test_ib.py 0000664 0000000 0000000 00000000567 13221545743 0025702 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_ib.protocolentities.ib import IbProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class IbProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = IbProtocolEntity
self.node = ProtocolTreeNode("ib")
yowsup-2.5.7/yowsup/layers/protocol_ib/protocolentities/test_offline_iq.py 0000664 0000000 0000000 00000000736 13221545743 0027421 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_ib.protocolentities.test_ib import IbProtocolEntityTest
from yowsup.layers.protocol_ib.protocolentities.offline_ib import OfflineIbProtocolEntity
from yowsup.structs import ProtocolTreeNode
class OfflineIbProtocolEntityTest(IbProtocolEntityTest):
def setUp(self):
super(OfflineIbProtocolEntityTest, self).setUp()
self.ProtocolEntity = OfflineIbProtocolEntity
self.node.addChild(ProtocolTreeNode("offline", {"count": "5"})) yowsup-2.5.7/yowsup/layers/protocol_iq/ 0000775 0000000 0000000 00000000000 13221545743 0020300 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_iq/__init__.py 0000664 0000000 0000000 00000000045 13221545743 0022410 0 ustar 00root root 0000000 0000000 from .layer import YowIqProtocolLayer yowsup-2.5.7/yowsup/layers/protocol_iq/layer.py 0000664 0000000 0000000 00000007534 13221545743 0021777 0 ustar 00root root 0000000 0000000 import time
import logging
from threading import Thread, Lock
from yowsup.layers import YowProtocolLayer, YowLayerEvent, EventCallback
from yowsup.common import YowConstants
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from .protocolentities import *
class YowIqProtocolLayer(YowProtocolLayer):
PROP_PING_INTERVAL = "org.openwhatsapp.yowsup.prop.pinginterval"
def __init__(self):
handleMap = {
"iq": (self.recvIq, self.sendIq)
}
self._pingThread = None
self._pingQueue = {}
self._pingQueueLock = Lock()
self.__logger = logging.getLogger(__name__)
super(YowIqProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Iq Layer"
def onPong(self, protocolTreeNode, pingEntity):
self.gotPong(pingEntity.getId())
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(protocolTreeNode))
def sendIq(self, entity):
if entity.getXmlns() == "w:p":
self._sendIq(entity, self.onPong)
elif entity.getXmlns() in ("urn:xmpp:whatsapp:push", "w", "urn:xmpp:whatsapp:account", "encrypt"):
self.toLower(entity.toProtocolTreeNode())
def recvIq(self, node):
if node["xmlns"] == "urn:xmpp:ping":
entity = PongResultIqProtocolEntity(YowConstants.DOMAIN, node["id"])
self.toLower(entity.toProtocolTreeNode())
def gotPong(self, pingId):
self._pingQueueLock.acquire()
if pingId in self._pingQueue:
self._pingQueue = {}
self._pingQueueLock.release()
def waitPong(self, id):
self._pingQueueLock.acquire()
self._pingQueue[id] = None
pingQueueSize = len(self._pingQueue)
self._pingQueueLock.release()
self.__logger.debug("ping queue size: %d" % pingQueueSize)
if pingQueueSize >= 2:
self.getStack().broadcastEvent(YowLayerEvent(YowNetworkLayer.EVENT_STATE_DISCONNECT, reason = "Ping Timeout"))
@EventCallback(YowAuthenticationProtocolLayer.EVENT_AUTHED)
def onAuthed(self, event):
interval = self.getProp(self.__class__.PROP_PING_INTERVAL, 50)
if not self._pingThread and interval > 0:
self._pingQueue = {}
self._pingThread = YowPingThread(self, interval)
self.__logger.debug("starting ping thread.")
self._pingThread.start()
def stop_thread(self):
if self._pingThread:
self.__logger.debug("stopping ping thread")
if self._pingThread:
self._pingThread.stop()
self._pingThread = None
self._pingQueue = {}
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECT)
def onDisconnect(self, event):
self.stop_thread()
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
def onDisconnected(self, event):
self.stop_thread()
class YowPingThread(Thread):
def __init__(self, layer, interval):
assert type(layer) is YowIqProtocolLayer, "layer must be a YowIqProtocolLayer, got %s instead." % type(layer)
self._layer = layer
self._interval = interval
self._stop = False
self.__logger = logging.getLogger(__name__)
super(YowPingThread, self).__init__()
self.daemon = True
self.name = "YowPing%s" % self.name
def run(self):
while not self._stop:
for i in range(0, self._interval):
time.sleep(1)
if self._stop:
self.__logger.debug("%s - ping thread stopped" % self.name)
return
ping = PingIqProtocolEntity()
self._layer.waitPong(ping.getId())
if not self._stop:
self._layer.sendIq(ping)
def stop(self):
self._stop = True
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0023706 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/__init__.py 0000664 0000000 0000000 00000000540 13221545743 0026016 0 ustar 00root root 0000000 0000000 from .iq import IqProtocolEntity
from .iq_result import ResultIqProtocolEntity
from .iq_ping import PingIqProtocolEntity
from .iq_result_pong import PongResultIqProtocolEntity
from .iq_error import ErrorIqProtocolEntity
from .iq_push import PushIqProtocolEntity
from .iq_props import PropsIqProtocolEntity
from .iq_crypto import CryptoIqProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq.py 0000664 0000000 0000000 00000004331 13221545743 0024672 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class IqProtocolEntity(ProtocolEntity):
'''
'''
TYPE_SET = "set"
TYPE_GET = "get"
TYPE_ERROR = "error"
TYPE_RESULT = "result"
TYPES = (TYPE_SET, TYPE_GET, TYPE_RESULT, TYPE_ERROR)
def __init__(self, xmlns = None, _id = None, _type = None, to = None, _from = None):
super(IqProtocolEntity, self).__init__("iq")
assert _type in self.__class__.TYPES, "Iq of type %s is not implemented, can accept only (%s)" % (_type," | ".join(self.__class__.TYPES))
assert not to or not _from, "Can't set from and to at the same time"
self._id = self._generateId(True) if _id is None else _id
self._from = _from
self._type = _type
self.xmlns = xmlns
self.to = to
def getId(self):
return self._id
def getType(self):
return self._type
def getXmlns(self):
return self.xmlns
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def getTo(self):
return self.to
def toProtocolTreeNode(self):
attribs = {
"id" : self._id,
"type" : self._type
}
if self.xmlns:
attribs["xmlns"] = self.xmlns
if self.to:
attribs["to"] = self.to
elif self._from:
attribs["from"] = self._from
return self._createProtocolTreeNode(attribs, None, data = None)
def __str__(self):
out = "Iq:\n"
out += "ID: %s\n" % self._id
out += "Type: %s\n" % self._type
if self.xmlns:
out += "xmlns: %s\n" % self.xmlns
if self.to:
out += "to: %s\n" % self.to
elif self._from:
out += "from: %s\n" % self._from
return out
@staticmethod
def fromProtocolTreeNode(node):
return IqProtocolEntity(
node.getAttributeValue("xmlns"),
node.getAttributeValue("id"),
node.getAttributeValue("type"),
node.getAttributeValue("to"),
node.getAttributeValue("from")
)
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_crypto.py 0000664 0000000 0000000 00000001213 13221545743 0026266 0 ustar 00root root 0000000 0000000 from .iq import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class CryptoIqProtocolEntity(IqProtocolEntity):
def __init__(self):
super(CryptoIqProtocolEntity, self).__init__("urn:xmpp:whatsapp:account", _type="get")
def toProtocolTreeNode(self):
node = super(CryptoIqProtocolEntity, self).toProtocolTreeNode()
cryptoNode = ProtocolTreeNode("crypto", {"action": "create"})
googleNode = ProtocolTreeNode("google", data = "fe5cf90c511fb899781bbed754577098e460d048312c8b36c11c91ca4b49ca34".decode('hex'))
cryptoNode.addChild(googleNode)
node.addChild(cryptoNode)
return node yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_error.py 0000664 0000000 0000000 00000003155 13221545743 0026106 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from .iq import IqProtocolEntity
class ErrorIqProtocolEntity(IqProtocolEntity):
'''
'''
def __init__(self, _id, _from, code, text, backoff= 0 ):
super(ErrorIqProtocolEntity, self).__init__(xmlns = None, _id = _id, _type = "error", _from = _from)
self.setErrorProps(code, text, backoff)
def setErrorProps(self, code, text, backoff):
self.code = code
self.text = text
self.backoff = int(backoff) if backoff else 0
def toProtocolTreeNode(self):
node = super(ErrorIqProtocolEntity, self).toProtocolTreeNode()
errorNode = ProtocolTreeNode("error", {"text": self.text, "code": self.code})
if self.backoff:
errorNode.setAttribute("backoff", str(self.backoff))
node.addChild(errorNode)
return node
def __str__(self):
out = super(ErrorIqProtocolEntity, self).__str__()
out += "Code: %s\n" % self.code
out += "Text: %s\n" % self.text
out += "Backoff: %s\n" % self.backoff
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ErrorIqProtocolEntity
errorNode = node.getChild("error")
entity.setErrorProps(errorNode.getAttributeValue("code"),
errorNode.getAttributeValue("text"),
errorNode.getAttributeValue("backoff"))
return entity
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_ping.py 0000664 0000000 0000000 00000001053 13221545743 0025705 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq import IqProtocolEntity
class PingIqProtocolEntity(IqProtocolEntity):
'''
Receive
Send
'''
def __init__(self, _from = None, to = None, _id = None):
super(PingIqProtocolEntity, self).__init__("urn:xmpp:ping" if _from else "w:p", _id = _id, _type = "get", _from = _from, to = to)
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_props.py 0000664 0000000 0000000 00000000610 13221545743 0026111 0 ustar 00root root 0000000 0000000 from .iq import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class PropsIqProtocolEntity(IqProtocolEntity):
def __init__(self):
super(PropsIqProtocolEntity, self).__init__("w", _type="get")
def toProtocolTreeNode(self):
node = super(PropsIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("props"))
return node yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_push.py 0000664 0000000 0000000 00000000633 13221545743 0025732 0 ustar 00root root 0000000 0000000 from .iq import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class PushIqProtocolEntity(IqProtocolEntity):
def __init__(self):
super(PushIqProtocolEntity, self).__init__("urn:xmpp:whatsapp:push", _type="get")
def toProtocolTreeNode(self):
node = super(PushIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("config"))
return node yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_result.py 0000664 0000000 0000000 00000000641 13221545743 0026270 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq import IqProtocolEntity
class ResultIqProtocolEntity(IqProtocolEntity):
'''
'''
def __init__(self, xmlns = None, _id = None, to = None, _from = None):
super(ResultIqProtocolEntity, self).__init__(xmlns = xmlns, _id = _id, _type = "result", to = to, _from = _from)
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/iq_result_pong.py 0000664 0000000 0000000 00000000604 13221545743 0027312 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_result import ResultIqProtocolEntity
class PongResultIqProtocolEntity(ResultIqProtocolEntity):
'''
'''
def __init__(self, to, _id = None):
super(PongResultIqProtocolEntity, self).__init__("w:p", _id = _id, to = to)
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/test_iq.py 0000664 0000000 0000000 00000000671 13221545743 0025734 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.iq import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class IqProtocolEntityTest(unittest.TestCase, ProtocolEntityTest):
def setUp(self):
self.ProtocolEntity = IqProtocolEntity
self.node = ProtocolTreeNode("iq", {"id": "test_id", "type": "get", "xmlns": "iq_xmlns"}, None, None) yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/test_iq_error.py 0000664 0000000 0000000 00000000771 13221545743 0027146 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class ErrorIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(ErrorIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = ErrorIqProtocolEntity
errorNode = ProtocolTreeNode("error", {"code": "123", "text": "abc"})
self.node.addChild(errorNode)
yowsup-2.5.7/yowsup/layers/protocol_iq/protocolentities/test_iq_result.py 0000664 0000000 0000000 00000000411 13221545743 0027322 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
class ResultIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(ResultIqProtocolEntityTest, self).setUp()
self.node.setAttribute("type", "result") yowsup-2.5.7/yowsup/layers/protocol_media/ 0000775 0000000 0000000 00000000000 13221545743 0020746 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_media/__init__.py 0000664 0000000 0000000 00000000052 13221545743 0023054 0 ustar 00root root 0000000 0000000 from .layer import YowMediaProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_media/layer.py 0000664 0000000 0000000 00000006600 13221545743 0022436 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import ImageDownloadableMediaMessageProtocolEntity
from .protocolentities import AudioDownloadableMediaMessageProtocolEntity
from .protocolentities import VideoDownloadableMediaMessageProtocolEntity
from .protocolentities import LocationMediaMessageProtocolEntity
from .protocolentities import VCardMediaMessageProtocolEntity
from .protocolentities import RequestUploadIqProtocolEntity, ResultRequestUploadIqProtocolEntity
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity, ErrorIqProtocolEntity
class YowMediaProtocolLayer(YowProtocolLayer):
# EVENT_REQUEST_UPLOAD = "org.openwhatsapp.org.yowsup.event.protocol_media.request_upload"
def __init__(self):
handleMap = {
"message": (self.recvMessageStanza, self.sendMessageEntity),
"iq": (self.recvIq, self.sendIq)
}
super(YowMediaProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Media Layer"
# def onEvent(self, yowLayerEvent):
# if yowLayerEvent.getArg(self.__class__.EVENT_REQUEST_UPLOAD):
# fpath = yowLayerEvent.getArg("file")
# _type = yowLayerEvent.getArg("type")
# assert fpath and _type, "Must specify 'file' and 'type' in EVENT_REQUEST_UPLOAD args"
# entity = RequestUploadIqProtocolEntity(_type, filePath=fpath)
# self._sendIq(entity, self.onRequestUploadSuccess, self.onRequestUploadError)
def sendMessageEntity(self, entity):
if entity.getType() == "media":
self.entityToLower(entity)
def recvMessageStanza(self, node):
if node.getAttributeValue("type") == "media":
mediaNode = node.getChild("media")
if mediaNode.getAttributeValue("type") == "image":
entity = ImageDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
elif mediaNode.getAttributeValue("type") == "audio":
entity = AudioDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
elif mediaNode.getAttributeValue("type") == "video":
entity = VideoDownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
elif mediaNode.getAttributeValue("type") == "location":
entity = LocationMediaMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
elif mediaNode.getAttributeValue("type") == "vcard":
entity = VCardMediaMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
def sendIq(self, entity):
"""
:type entity: IqProtocolEntity
"""
if entity.getType() == IqProtocolEntity.TYPE_SET and entity.getXmlns() == "w:m":
#media upload!
self._sendIq(entity, self.onRequestUploadSuccess, self.onRequestUploadError)
def recvIq(self, node):
"""
:type node: ProtocolTreeNode
"""
def onRequestUploadSuccess(self, resultNode, requestUploadEntity):
self.toUpper(ResultRequestUploadIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onRequestUploadError(self, errorNode, requestUploadEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
yowsup-2.5.7/yowsup/layers/protocol_media/mediadownloader.py 0000664 0000000 0000000 00000004013 13221545743 0024454 0 ustar 00root root 0000000 0000000 import sys, tempfile, logging
logger = logging.getLogger(__name__)
if sys.version_info >= (3, 0):
from urllib.request import urlopen
from urllib.parse import urlencode
else:
from urllib2 import urlopen
from urllib import urlencode
class MediaDownloader:
def __init__(self, successClbk = None, errorClbk = None, progressCallback = None):
self.successCallback = successClbk
self.errorCallback = errorClbk
self.progressCallback = progressCallback
def download(self, url = ""):
try:
if not url:
if self.url:
url = "https://" if self.port == 443 else "http://"
url = url + self.url
url = url + "?" + urlencode(self.params)
logger.debug("URL is %s" % url)
else:
raise Exception("No url specified for fetching")
u = urlopen(url)
path = tempfile.mkstemp()[1]
with open(path, "wb") as f:
meta = u.info()
if sys.version_info >= (3, 0):
fileSize = int(u.getheader("Content-Length"))
else:
fileSize = int(meta.getheaders("Content-Length")[0])
fileSizeDl = 0
blockSz = 8192
lastEmit = 0
while True:
buf = u.read(blockSz)
if not buf:
break
fileSizeDl += len(buf)
f.write(buf)
status = (fileSizeDl * 100 / fileSize)
if self.progressCallback and lastEmit != status:
self.progressCallback(int(status))
lastEmit = status;
if self.successCallback:
self.successCallback(path)
except:
logger.exception("Error occured at transfer")
if self.errorCallback:
self.errorCallback(); yowsup-2.5.7/yowsup/layers/protocol_media/mediauploader.py 0000664 0000000 0000000 00000012041 13221545743 0024131 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
import socket, ssl, os, hashlib, sys
from time import sleep
import threading
import logging
from yowsup.common.tools import MimeTools
logger = logging.getLogger(__name__)
class MediaUploader(WARequest, threading.Thread):
def __init__(self, jid, accountJid, sourcePath, uploadUrl, resumeOffset = 0, successClbk = None, errorClbk = None, progressCallback = None, async = True):
WARequest.__init__(self)
self.async = async
self.jid = jid
self.accountJid = accountJid
self.sourcePath = sourcePath
self.uploadUrl = uploadUrl
self.resumeOffset = resumeOffset
self.successCallback = successClbk
self.errorCallback = errorClbk
self.progressCallback = progressCallback
self.pvars = ["name", "type", "size", "url", "error", "mimetype", "filehash", "width", "height"]
self.setParser(JSONResponseParser())
self.sock = socket.socket()
def start(self):
if self.async:
threading.Thread.__init__(self)
super(MediaUploader, self).start()
else:
self.run()
def run(self):
sourcePath = self.sourcePath
uploadUrl = self.uploadUrl
_host = uploadUrl.replace("https://","")
self.url = _host[:_host.index('/')]
try:
filename = os.path.basename(sourcePath)
filetype = MimeTools.getMIME(filename)
filesize = os.path.getsize(sourcePath)
self.sock.connect((self.url, self.port))
ssl_sock = ssl.wrap_socket(self.sock)
m = hashlib.md5()
m.update(filename.encode())
crypto = m.hexdigest() + os.path.splitext(filename)[1]
boundary = "zzXXzzYYzzXXzzQQ"#"-------" + m.hexdigest() #"zzXXzzYYzzXXzzQQ"
contentLength = 0
hBAOS = "--" + boundary + "\r\n"
hBAOS += "Content-Disposition: form-data; name=\"to\"\r\n\r\n"
hBAOS += self.jid + "\r\n"
hBAOS += "--" + boundary + "\r\n"
hBAOS += "Content-Disposition: form-data; name=\"from\"\r\n\r\n"
hBAOS += self.accountJid.replace("@whatsapp.net","") + "\r\n"
hBAOS += "--" + boundary + "\r\n"
hBAOS += "Content-Disposition: form-data; name=\"file\"; filename=\"" + crypto + "\"\r\n"
hBAOS += "Content-Type: " + filetype + "\r\n\r\n"
fBAOS = "\r\n--" + boundary + "--\r\n"
contentLength += len(hBAOS)
contentLength += len(fBAOS)
contentLength += filesize
POST = "POST %s\r\n" % uploadUrl
POST += "Content-Type: multipart/form-data; boundary=" + boundary + "\r\n"
POST += "Host: %s\r\n" % self.url
POST += "User-Agent: %s\r\n" % self.getUserAgent()
POST += "Content-Length: " + str(contentLength) + "\r\n\r\n"
ssl_sock.write(bytearray(POST.encode()))
ssl_sock.write(bytearray(hBAOS.encode()))
totalsent = 0
buf = 1024
f = open(sourcePath, 'rb')
stream = f.read()
f.close()
status = 0
lastEmit = 0
while totalsent < int(filesize):
ssl_sock.write(stream[:buf])
status = totalsent * 100 / filesize
if lastEmit!=status and status!=100 and filesize>12288:
if self.progressCallback:
self.progressCallback(self.sourcePath, self.jid, uploadUrl, int(status))
lastEmit = status
stream = stream[buf:]
totalsent = totalsent + buf
ssl_sock.write(bytearray(fBAOS.encode()))
sleep(1)
data = ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
data += ssl_sock.recv(8192)
if self.progressCallback:
self.progressCallback(self.sourcePath, self.jid, uploadUrl, 100)
lines = data.decode().splitlines()
result = None
for l in lines:
if l.startswith("{"):
result = self.parser.parse(l, self.pvars)
break
if not result:
raise Exception("json data not found")
if result["url"] is not None:
if self.successCallback:
self.successCallback(sourcePath, self.jid, result["url"])
else:
logger.exception("uploadUrl: %s, result of uploading media has no url" % uploadUrl)
if self.errorCallback:
self.errorCallback(sourcePath, self.jid, uploadUrl)
except:
logger.exception("Error occured at transfer %s"%sys.exc_info()[1])
if self.errorCallback:
self.errorCallback(sourcePath, self.jid, uploadUrl)
yowsup-2.5.7/yowsup/layers/protocol_media/picture.py 0000664 0000000 0000000 00000002073 13221545743 0022775 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer
from yowsup import ProtocolTreeNode
from .mediadownloader import MediaDownloader
import shutil, os, logging
logger = logging.getLogger(__name__)
class YowMediaPictureLayer(YowLayer):
def send(self, data):
self.toLower(data)
def receive(self, node):
if ProtocolTreeNode.tagEquals(node, "message") and node.getAttributeValue("type") == "media":
self.downloadMedia(node.getChild("media").getAttributeValue("url"))
else:
self.toUpper(node)
def downloadMedia(self, url):
logger.debug("Downloading %s" % url)
downloader = MediaDownloader(self.onSuccess, self.onError, self.onProgress)
downloader.download(url)
def onError(self):
logger.error("Error download file")
def onSuccess(self, path):
outPath = "/tmp/yowfiles/%s.jpg" % os.path.basename(path)
shutil.copyfile(path, outPath)
logger.debug("Picture downloaded to %s" % outPath)
def onProgress(self, progress):
logger.debug("Download progress %s" % progress)
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0024354 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/__init__.py 0000664 0000000 0000000 00000001240 13221545743 0026462 0 ustar 00root root 0000000 0000000 from .message_media import MediaMessageProtocolEntity
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
from .message_media_downloadable_image import ImageDownloadableMediaMessageProtocolEntity
from .message_media_downloadable_audio import AudioDownloadableMediaMessageProtocolEntity
from .message_media_downloadable_video import VideoDownloadableMediaMessageProtocolEntity
from .message_media_location import LocationMediaMessageProtocolEntity
from .message_media_vcard import VCardMediaMessageProtocolEntity
from .iq_requestupload import RequestUploadIqProtocolEntity
from .iq_requestupload_result import ResultRequestUploadIqProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/builder_message_media_downloadable.py 0000664 0000000 0000000 00000003536 13221545743 0033741 0 ustar 00root root 0000000 0000000 # from yowsup.layers.protocol_media import mediacipher
import tempfile
import os
class DownloadableMediaMessageBuilder(object):
def __init__(self, downloadbleMediaMessageClass, jid, filepath):
self.jid = jid
self.filepath = filepath
self.encryptedFilepath = None
self.cls = downloadbleMediaMessageClass
self.mediaKey = None
self.attributes = {}
self.mediaType = self.cls.__name__.split("DownloadableMediaMessageProtocolEntity")[0].lower() #ugly ?
# def encrypt(self):
# fd, encpath = tempfile.mkstemp()
# mediaKey = os.urandom(112)
# keys = mediacipher.getDerivedKeys(mediaKey)
# out = mediacipher.encryptImage(self.filepath, keys)
# with open(encImagePath, 'w') as outF:
# outF.write(out)
#
# self.mediaKey = mediaKey
# self.encryptedFilepath = encpath
# def decrypt(self):
# self.mediaKey = None
# self.encryptedFilePath = None
def setEncryptionData(self, mediaKey, encryptedFilepath):
self.mediaKey = mediaKey
self.encryptedFilepath = encryptedFilepath
def isEncrypted(self):
return self.encryptedFilepath is not None
def getFilepath(self):
return self.encryptedFilepath or self.filepath
def getOriginalFilepath(self):
return self.filepath
def set(self, key, val):
self.attributes[key] = val
def get(self, key, default = None):
if key in self.attributes and self.attributes[key] is not None:
return self.attributes[key]
return default
def getOrSet(self, key, func):
if not self.get(key):
self.set(key, func())
def build(self, url = None, ip = None):
if url:
self.set("url", url)
if ip:
self.set("ip", ip)
return self.cls.fromBuilder(self)
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py 0000664 0000000 0000000 00000006176 13221545743 0030326 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
import hashlib
import base64
import os
from yowsup.common.tools import WATools
class RequestUploadIqProtocolEntity(IqProtocolEntity):
'''
'''
MEDIA_TYPE_IMAGE = "image"
MEDIA_TYPE_VIDEO = "video"
MEDIA_TYPE_AUDIO = "audio"
XMLNS = "w:m"
TYPES_MEDIA = (MEDIA_TYPE_AUDIO, MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO)
def __init__(self, mediaType, b64Hash = None, size = None, origHash = None, filePath = None ):
super(RequestUploadIqProtocolEntity, self).__init__("w:m", _type = "set", to = YowConstants.WHATSAPP_SERVER)
assert (b64Hash and size) or filePath, "Either specify hash and size, or specify filepath and let me generate the rest"
if filePath:
assert os.path.exists(filePath), "Either specified path does not exist, or yowsup doesn't have permission to read: %s" % filePath
b64Hash = self.__class__.getFileHashForUpload(filePath)
size = os.path.getsize(filePath)
self.setRequestArguments(mediaType, b64Hash, size, origHash)
def setRequestArguments(self, mediaType, b64Hash, size, origHash = None):
assert mediaType in self.__class__.TYPES_MEDIA, "Expected media type to be in %s, got %s" % (self.__class__.TYPES_MEDIA, mediaType)
self.mediaType = mediaType
self.b64Hash = b64Hash
self.size = int(size)
self.origHash = origHash
@staticmethod
def getFileHashForUpload(filePath):
return WATools.getFileHashForUpload(filePath)
def __str__(self):
out = super(RequestUploadIqProtocolEntity, self).__str__()
out += "Media Type: %s\n" % self.mediaType
out += "B64Hash: %s\n" % self.b64Hash
out += "Size: %s\n" % self.size
if self.origHash:
out += "OrigHash: %s\n" % self.origHash
return out
def toProtocolTreeNode(self):
node = super(RequestUploadIqProtocolEntity, self).toProtocolTreeNode()
attribs = {
"hash": self.b64Hash,
"type": self.mediaType,
"size": str(self.size)
}
if self.origHash:
attribs["orighash"] = self.origHash
mediaNode = ProtocolTreeNode("media", attribs)
node.addChild(mediaNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
assert node.getAttributeValue("type") == "set", "Expected set as iq type in request upload, got %s" % node.getAttributeValue("type")
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = RequestUploadIqProtocolEntity
mediaNode = node.getChild("media")
entity.setRequestArguments(
mediaNode.getAttributeValue("type"),
mediaNode.getAttributeValue("hash"),
mediaNode.getAttributeValue("size"),
mediaNode.getAttributeValue("orighash")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py 0000664 0000000 0000000 00000004244 13221545743 0031716 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class ResultRequestUploadIqProtocolEntity(ResultIqProtocolEntity):
def __init__(self, _id, url, ip = None, resumeOffset = 0, duplicate = False):
super(ResultRequestUploadIqProtocolEntity, self).__init__(_id = _id, _from = YowConstants.WHATSAPP_SERVER)
self.setUploadProps(url, ip, resumeOffset, duplicate)
def setUploadProps(self, url ,ip = None, resumeOffset = 0, duplicate = False):
self.url = url
self.ip = ip
self.resumeOffset = resumeOffset or 0
self.duplicate = duplicate
def isDuplicate(self):
return self.duplicate
def getUrl(self):
return self.url
def getResumeOffset(self):
return self.resumeOffset
def getIp(self):
return self.ip
def __str__(self):
out = super(ResultRequestUploadIqProtocolEntity, self).__str__()
out += "URL: %s\n" % self.url
if self.ip:
out += "IP: %s\n" % self.ip
return out
def toProtocolTreeNode(self):
node = super(ResultRequestUploadIqProtocolEntity, self).toProtocolTreeNode()
if not self.isDuplicate():
mediaNode = ProtocolTreeNode("media", {"url": self.url})
if self.ip:
mediaNode["ip"] = self.ip
if self.resumeOffset:
mediaNode["resume"] = str(self.resumeOffset)
else:
mediaNode = ProtocolTreeNode("duplicate", {"url": self.url})
node.addChild(mediaNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity= ResultIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ResultRequestUploadIqProtocolEntity
mediaNode = node.getChild("media")
if mediaNode:
entity.setUploadProps(mediaNode["url"], mediaNode["ip"], mediaNode["resume"])
else:
duplicateNode = node.getChild("duplicate")
if duplicateNode:
entity.setUploadProps(duplicateNode["url"], duplicateNode["ip"], duplicate = True)
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media.py 0000664 0000000 0000000 00000016350 13221545743 0027516 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_messages.protocolentities import MessageProtocolEntity
class MediaMessageProtocolEntity(MessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
'''
{{THUMBNAIL_RAWDATA}}
{{THUMBNAIL_RAWDATA}}
BEGIN:VCARD
VERSION:3.0
N:Yasser;Hany;;;
FN:Hany Yasser
PHOTO;BASE64:/9j/4AAQSkZJRgABAQEASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAQABAAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLv/dAAQABP/aAAwDAQACEQMRAD8A83lPGaqzn/iXgnqZB/WpWbKjNV7kgWC5/wCen9DXix3PoGtCreFJG3OcbVFZmx2XL8A9PoOa9u0b4TDVLH+0tavDZMyBkiUDKqRkGQsQBkc49O9ebeJ9Am8PXX2bzkuYJAWhmjOVcA4Pc4I7jNelCm1BOx5M6kXNpM5VnX77EEn17D6Vt6aVaNtnABxitnwn4DvPEUS3lxIIoH5HG5yPUL059zVTxLoUPhDUYGs7gzRO+yXOCB6A7eOlTUSa5U9SqbcXzNaGdenbYxhevymsPc0rGVyDg9O1a96d9uPT5RWK/C/d6ck0qK0HXd5H/9Dy2U9B2rpPCNgmp6xp9vKgeNJWmdSMgrGN3P44qponhvVvE9ybLSYw8iKXYs21VHTk+56V7B4T8F3nhSKS91gx/anHlxqjbgqty2TgcnA/KvNo0m2n0PYr1oxi431F8R3d7Jef6MbaZ964huDhSCBlsZ5OfXp2rwzxZdyS6rLC0C26xuRhCNrkHbvAHTpivUvEdrdiaWZ4DIXXarrwVJ/oQce9eZXfg3WLgNc22ySNSIzufawc9Bz6116uTucbUYwSRreFb23sLCG6v72RraFjGbVOQwOeo78HjvTtavfDdvpyRWNo4LyIx3sSTg5xz3Hfr9a4n7Bd6bfW9orxSSSyBAqncpYnGDxx161614T8JXet3/8AbXidRHZaVuxDu3FmXLMWPp+XtxQqTk9Be2UYnj94ymFB64zWSxDnJ5UenGas3bmaWRkG1Gdii+iknA/AVQKsoyRwO1ONJxVmTKrGTuj/0e3+D9iLfR5tRZcSXUu0H/ZjxjH4k165fQG4tXRADJ/Dnpn3ri/BVt9h8OaXCMf6lSw772BY/wDoVdm90qSCPHJ6VUI2gkE581RyPNdQQJKVkj3smCpYZYY6Ae+elcT43e78M+F43twI57u4+Y4B25BYgA8cYHNe3ytbtK7lFLttwcc8nHX8K8V+OF5EdK0+BOrXJP4BD/jQkrlTk7aHjPgmztp/E8FxetsgtUluZH7hYULZ+oOK7XQEsNN+G2ra/bNMLu8mNmC8hI2uwwMdCdpJJOTnPSvOdNuPI0/V5lOG+wOg/wC2ksSH9Ca7DXwNH8A6Fpak7rxpL6X6kAL+QJrVLTQwe5545Qc9u1Z104cbe1Pkl3fSqW4szj8qzbLSP//S+ghGIfJjAA2gDHpgY49qZIxN2T2Rf1NULK5XVL66u4+YLaQ20ZH8Tp/rD+BO38DUyzlndWHclT6r2rVkR3KV7eLb3cELIx8zI3DGAM/mcdT6DmvBPjZdfvNLj6bvMfHoOAP0r6JMqujxnoyH9P8A9dfK/wAZrozeILeFOTHbDA9NzMSfyAqLblyZ57arv0vUmzjbbZ/8ixj+ddd8QbxpW0W0PHk6ZASB0G8Fq86ecx2c8Y6SIqn6bg39K6TxS0pv7dpTnNjabfZREuBWqfumdtTmpG2rmqUT/vDnvU07YGKpx4EoySvuKyZZ/9k=
BDAY;value=date:1989-01-05
ORG:Vodafone Egypt;
item1.EMAIL;type=INTERNET:hanyyasser@hotmail.com
item1.X-ABLabel:INTERNET
item2.EMAIL;type=INTERNET:hanybotbot@hotmail.com
item2.X-ABLabel:INTERNET
item3.ADR;type=HOME:;;Heliopolis;Cairo;Al Qahirah;;Egypt
item4.ADR;type=HOME:;;;cairo;;;Egypt
item5.URL:http://www.facebook.com/profile.php?id=626850952
item5.X-ABLabel:_$!!$_
X-FACEBOOK:hany.yasser1
END:VCARD
'''
MEDIA_TYPE_IMAGE = "image"
MEDIA_TYPE_VIDEO = "video"
MEDIA_TYPE_AUDIO = "audio"
MEDIA_TYPE_VCARD = "vcard"
MEDIA_TYPE_LOCATION = "location"
TYPES_MEDIA = (MEDIA_TYPE_AUDIO, MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO, MEDIA_TYPE_VCARD, MEDIA_TYPE_LOCATION)
def __init__(self, mediaType, _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None, preview = None, offline = None, retry = None):
super(MediaMessageProtocolEntity, self).__init__("media", _id, _from, to, notify, timestamp, participant, offline, retry)
self.setMediaType(mediaType)
self.setPreview(preview)
def __str__(self):
out = super(MediaMessageProtocolEntity, self).__str__()
out += "Media Type: %s\n" % self.mediaType
out += "Has Preview: %s\n" % (self.preview is not None)
return out
def setPreview(self, preview):
self.preview = preview
def getPreview(self):
return self.preview
def setMediaType(self, mediaType):
self.mediaType = mediaType
def getMediaType(self):
return self.mediaType
def toProtocolTreeNode(self):
node = super(MediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = ProtocolTreeNode("media", {"type": self.mediaType}, None, None)
node.addChild(mediaNode)
if self.preview:
mediaNode.setData(self.preview)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = MediaMessageProtocolEntity
entity.setMediaType(node.getChild("media").getAttributeValue("type"))
preview = node.getChild("media").getData()
entity.setPreview(preview)
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py 0000664 0000000 0000000 00000010026 13221545743 0032223 0 ustar 00root root 0000000 0000000 from .message_media import MediaMessageProtocolEntity
from yowsup.common.tools import WATools
from yowsup.common.tools import MimeTools
import os
class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
def __init__(self, mediaType,
mimeType, fileHash, url, ip, size, fileName, mediaKey = None,
_id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, preview = None, offline = None, retry = None):
super(DownloadableMediaMessageProtocolEntity, self).__init__(mediaType, _id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setDownloadableMediaProps(mimeType, fileHash, url, ip, size, fileName, mediaKey)
def __str__(self):
out = super(DownloadableMediaMessageProtocolEntity, self).__str__()
out += "MimeType: %s\n" % self.mimeType
out += "File Hash: %s\n" % self.fileHash.encode('hex')
out += "URL: %s\n" % self.url
out += "IP: %s\n" % self.ip
out += "File Size: %s\n" % self.size
out += "File name: %s\n" % self.fileName
return out
def getMediaSize(self):
return self.size
def getMediaUrl(self):
return self.url
def getMimeType(self):
return self.mimeType
def setDownloadableMediaProps(self, mimeType, fileHash, url, ip, size, fileName, mediaKey):
self.mimeType = mimeType
self.fileHash = fileHash
self.url = url
self.ip = ip
self.size = int(size)
self.fileName = fileName
self.mediaKey = mediaKey
def toProtocolTreeNode(self):
node = super(DownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
mediaNode.setAttribute("mimetype", self.mimeType)
mediaNode.setAttribute("filehash", self.fileHash)
mediaNode.setAttribute("url", self.url)
if self.ip:
mediaNode.setAttribute("ip", self.ip)
mediaNode.setAttribute("size", str(self.size))
mediaNode.setAttribute("file", self.fileName)
if self.mediaKey:
mediaNode.setAttribute("mediakey", self.mediaKey)
return node
def isEncrypted(self):
return self.mediaKey is not None
@staticmethod
def fromProtocolTreeNode(node):
entity = MediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = DownloadableMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setDownloadableMediaProps(
mediaNode.getAttributeValue("mimetype"),
mediaNode.getAttributeValue("filehash"),
mediaNode.getAttributeValue("url"),
mediaNode.getAttributeValue("ip"),
mediaNode.getAttributeValue("size"),
mediaNode.getAttributeValue("file"),
mediaNode.getAttributeValue("mediakey")
)
return entity
@staticmethod
def fromBuilder(builder):
url = builder.get("url")
ip = builder.get("ip")
assert url, "Url is required"
mimeType = builder.get("mimetype", MimeTools.getMIME(builder.getOriginalFilepath())[0])
filehash = WATools.getFileHashForUpload(builder.getFilepath())
size = os.path.getsize(builder.getFilepath())
fileName = os.path.basename(builder.getFilepath())
return DownloadableMediaMessageProtocolEntity(builder.mediaType, mimeType, filehash, url, ip, size, fileName, to = builder.jid, preview = builder.get("preview"))
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py 0000664 0000000 0000000 00000010167 13221545743 0033412 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
class AudioDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
def __init__(self,
mimeType, fileHash, url, ip, size, fileName,
abitrate, acodec, asampfreq, duration, encoding, origin, seconds,
_id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, preview = None, offline = None, retry = None):
super(AudioDownloadableMediaMessageProtocolEntity, self).__init__("audio",
mimeType, fileHash, url, ip, size, fileName, None,
_id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setAudioProps(abitrate, acodec, asampfreq, duration, encoding, origin, seconds)
def __str__(self):
out = super(AudioDownloadableMediaMessageProtocolEntity, self).__str__()
out += "Bitrate: %s\n" % self.abitrate
out += "Codec: %s\n" % self.acodec
out += "Duration: %s\n" % self.duration
out += "Encoding: %s\n" % self.encoding
out += "Origin: %s\n" % self.origin
out += "Sampling freq.: %s\n" % self.asampfreq
return out
def setAudioProps(self, abitrate = None, acodec = None, asampfreq = None,
duration = None, encoding = None, origin = None, seconds = None):
self.abitrate = abitrate
self.acodec = acodec
self.asampfreq = asampfreq
self.duration = duration
self.encoding = encoding
self.origin = origin
self.seconds = seconds
def toProtocolTreeNode(self):
node = super(AudioDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
if self.abitrate:
mediaNode.setAttribute("abitrate", self.abitrate)
if self.acodec:
mediaNode.setAttribute("acodec", self.acodec)
if self.asampfreq:
mediaNode.setAttribute("asampfreq", self.asampfreq)
if self.duration:
mediaNode.setAttribute("duration", self.duration)
if self.encoding:
mediaNode.setAttribute("encoding", self.encoding)
if self.origin:
mediaNode.setAttribute("origin", self.origin)
if self.seconds:
mediaNode.setAttribute("seconds", self.seconds)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = DownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = AudioDownloadableMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setAudioProps(
mediaNode.getAttributeValue("abitrate"),
mediaNode.getAttributeValue("acodec"),
mediaNode.getAttributeValue("asampfreq"),
mediaNode.getAttributeValue("duration"),
mediaNode.getAttributeValue("encoding"),
mediaNode.getAttributeValue("origin"),
mediaNode.getAttributeValue("seconds"),
)
return entity
@staticmethod
def fromFilePath(fpath, url, ip, to, mimeType = None, preview = None, filehash = None, filesize = None):
entity = DownloadableMediaMessageProtocolEntity.fromFilePath(fpath, url, DownloadableMediaMessageProtocolEntity.MEDIA_TYPE_AUDIO, ip, to, mimeType, preview)
entity.__class__ = AudioDownloadableMediaMessageProtocolEntity
entity.setAudioProps()
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py 0000664 0000000 0000000 00000011640 13221545743 0033370 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
from .builder_message_media_downloadable import DownloadableMediaMessageBuilder
from yowsup.layers.protocol_messages.proto.wa_pb2 import ImageMessage
from yowsup.common.tools import ImageTools
class ImageDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
def __init__(self,
mimeType, fileHash, url, ip, size, fileName,
encoding, width, height, caption = None, mediaKey = None,
_id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, preview = None, offline = None, retry = None):
super(ImageDownloadableMediaMessageProtocolEntity, self).__init__("image",
mimeType, fileHash, url, ip, size, fileName, mediaKey,
_id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setImageProps(encoding, width, height, caption)
def __str__(self):
out = super(ImageDownloadableMediaMessageProtocolEntity, self).__str__()
out += "Encoding: %s\n" % self.encoding
out += "Width: %s\n" % self.width
out += "Height: %s\n" % self.height
if self.caption:
out += "Caption: %s\n" % self.caption
return out
def setImageProps(self, encoding, width, height, caption):
self.encoding = encoding
self.width = int(width)
self.height = int(height)
self.caption = caption
def getCaption(self):
return self.caption
def toProtocolTreeNode(self):
node = super(ImageDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
mediaNode.setAttribute("encoding", self.encoding)
mediaNode.setAttribute("width", str(self.width))
mediaNode.setAttribute("height", str(self.height))
if self.caption:
mediaNode.setAttribute("caption", self.caption)
return node
def toProtobufMessage(self):
image_message = ImageMessage()
image_message.url = self.url
image_message.width = self.width
image_message.height = self.height
image_message.mime_type = self.mimeType
image_message.file_sha256 = self.fileHash
image_message.file_length = self.size
image_message.caption = self.caption
image_message.jpeg_thumbnail = self.preview
image_message.media_key = self.mediaKey
return image_message
@staticmethod
def fromProtocolTreeNode(node):
entity = DownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ImageDownloadableMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setImageProps(
mediaNode.getAttributeValue("encoding"),
mediaNode.getAttributeValue("width"),
mediaNode.getAttributeValue("height"),
mediaNode.getAttributeValue("caption"),
)
return entity
@staticmethod
def getBuilder(jid, filepath):
return DownloadableMediaMessageBuilder(ImageDownloadableMediaMessageProtocolEntity, jid, filepath)
@staticmethod
def fromBuilder(builder):
builder.getOrSet("preview", lambda: ImageTools.generatePreviewFromImage(builder.getOriginalFilepath()))
filepath = builder.getFilepath()
caption = builder.get("caption")
dimensions = builder.get("dimensions", ImageTools.getImageDimensions(builder.getOriginalFilepath()))
assert dimensions, "Could not determine image dimensions"
width, height = dimensions
entity = DownloadableMediaMessageProtocolEntity.fromBuilder(builder)
entity.__class__ = builder.cls
entity.setImageProps("raw", width, height, caption)
return entity
@staticmethod
def fromFilePath(path, url, ip, to, mimeType = None, caption = None, dimensions = None):
builder = ImageDownloadableMediaMessageProtocolEntity.getBuilder(to, path)
builder.set("url", url)
builder.set("ip", ip)
builder.set("caption", caption)
builder.set("mimetype", mimeType)
builder.set("dimensions", dimensions)
return ImageDownloadableMediaMessageProtocolEntity.fromBuilder(builder)
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py 0000664 0000000 0000000 00000014446 13221545743 0033423 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
from yowsup.common.tools import VideoTools
class VideoDownloadableMediaMessageProtocolEntity(DownloadableMediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
def __init__(self,
mimeType, fileHash, url, ip, size, fileName,
abitrate, acodec, asampfmt, asampfreq, duration, encoding, fps,
width, height, seconds, vbitrate, vcodec, caption = None,
_id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, preview = None, offline = None, retry = None):
super(VideoDownloadableMediaMessageProtocolEntity, self).__init__("video",
mimeType, fileHash, url, ip, size, fileName, None,
_id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setVideoProps(encoding, width, height, vbitrate, abitrate, acodec, asampfmt, asampfreq, duration, fps, seconds, vcodec, caption)
def __str__(self):
out = super(VideoDownloadableMediaMessageProtocolEntity, self).__str__()
out += "Audio bitrate: %s\n" % self.abitrate
out += "Audio codec: %s\n" % self.acodec
out += "Audio sampling fmt.: %s\n" % self.asampfmt
out += "Audio sampling freq.: %s\n" % self.asampfreq
out += "Duration: %s\n" % self.duration
out += "Encoding: %s\n" % self.encoding
out += "Fps: %s\n" % self.fps
out += "Width: %s\n" % self.width
out += "Height: %s\n" % self.height
out += "Video bitrate: %s\n" % self.vbitrate
out += "Video codec: %s\n" % self.vcodec
if self.caption is not None:
out += "Caption: %s\n" % self.caption
return out
def setVideoProps(self, encoding, width, height, vbitrate = None, abitrate = None, acodec = None, asampfmt = None, asampfreq = None, duration = None, fps = None, seconds = None, vcodec = None, caption = None,):
self.abitrate = abitrate
self.acodec = acodec
self.asampfmt = asampfmt
self.asampfreq = asampfreq
self.duration = duration
self.encoding = encoding
self.fps = fps
self.height = height
self.seconds = seconds
self.vbitrate = vbitrate
self.vcodec = vcodec
self.width = width
self.caption = caption
def getCaption(self):
return self.caption
def toProtocolTreeNode(self):
node = super(VideoDownloadableMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
mediaNode.setAttribute("abitrate", self.abitrate)
mediaNode.setAttribute("acodec", self.acodec)
mediaNode.setAttribute("asampfmt", self.asampfmt)
mediaNode.setAttribute("asampfreq", self.asampfreq)
mediaNode.setAttribute("duration", self.duration)
mediaNode.setAttribute("encoding", self.encoding)
mediaNode.setAttribute("height", str(self.height))
mediaNode.setAttribute("width", str(self.width))
if self.abitrate is not None:
mediaNode.setAttribute("abitrate", str(self.abitrate))
if self.acodec is not None:
mediaNode.setAttribute("acodec", self.acodec)
if self.asampfmt is not None:
mediaNode.setAttribute("asampfmt", self.asampfmt)
if self.asampfreq is not None:
mediaNode.setAttribute("asampfreq", str(self.asampfreq))
if self.duration is not None:
mediaNode.setAttribute("duration", str(self.duration))
if self.fps is not None:
mediaNode.setAttribute("fps", str(self.fps))
if self.seconds is not None:
mediaNode.setAttribute("seconds", str(self.seconds))
if self.vbitrate is not None:
mediaNode.setAttribute("vbitrate", str(self.vbitrate))
if self.vcodec is not None:
mediaNode.setAttribute("vcodec", self.vcodec)
if self.caption is not None:
mediaNode.setAttribute("caption", self.caption)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = DownloadableMediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = VideoDownloadableMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setVideoProps(
mediaNode.getAttributeValue("encoding"),
mediaNode.getAttributeValue("width"),
mediaNode.getAttributeValue("height"),
mediaNode.getAttributeValue("vbitrate"),
mediaNode.getAttributeValue("abitrate"),
mediaNode.getAttributeValue("acodec"),
mediaNode.getAttributeValue("asampfmt"),
mediaNode.getAttributeValue("asampfreq"),
mediaNode.getAttributeValue("duration"),
mediaNode.getAttributeValue("fps"),
mediaNode.getAttributeValue("seconds"),
mediaNode.getAttributeValue("vcodec"),
mediaNode.getAttributeValue("caption")
)
return entity
@staticmethod
def fromFilePath(path, url, ip, to, mimeType = None, caption = None):
preview = VideoTools.generatePreviewFromVideo(path)
entity = DownloadableMediaMessageProtocolEntity.fromFilePath(path, url, DownloadableMediaMessageProtocolEntity.MEDIA_TYPE_VIDEO, ip, to, mimeType, preview)
entity.__class__ = VideoDownloadableMediaMessageProtocolEntity
width, height, bitrate, duration = VideoTools.getVideoProperties(path)
assert width, "Could not determine video properties"
duration = int(duration)
entity.setVideoProps('raw', width, height, duration=duration, seconds=duration, caption=caption)
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_location.py 0000664 0000000 0000000 00000005611 13221545743 0031404 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media import MediaMessageProtocolEntity
class LocationMediaMessageProtocolEntity(MediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA}}
'''
def __init__(self, latitude, longitude, name, url, encoding, _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None,
preview = None, offline = None, retry = None):
super(LocationMediaMessageProtocolEntity, self).__init__("location", _id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setLocationMediaProps(latitude,longitude,name,url,encoding)
def __str__(self):
out = super(MediaMessageProtocolEntity, self).__str__()
out += "Latitude: %s\n" % self.latitude
out += "Longitude: %s\n" % self.longitude
out += "Name: %s\n" % self.name
out += "URL: %s\n" % self.url
out += "Encoding: %s\n" % self.encoding
return out
def getLatitude(self):
return self.latitude
def getLongitude(self):
return self.longitude
def getLocationName(self):
return self.name
def getLocationURL(self):
return self.url
def setLocationMediaProps(self, latitude, longitude, locationName, url, encoding):
self.latitude = str(latitude)
self.longitude = str(longitude)
self.name = locationName
self.url = url
self.encoding= encoding
def toProtocolTreeNode(self):
node = super(LocationMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
mediaNode.setAttribute("latitude", self.latitude)
mediaNode.setAttribute("longitude", self.longitude)
mediaNode.setAttribute("encoding", self.encoding)
if self.name:
mediaNode.setAttribute("name", self.name)
if self.url:
mediaNode.setAttribute("url", self.url)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = LocationMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setLocationMediaProps(
mediaNode.getAttributeValue("latitude"),
mediaNode.getAttributeValue("longitude"),
mediaNode.getAttributeValue("name"),
mediaNode.getAttributeValue("url"),
mediaNode.getAttributeValue("encoding")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/message_media_vcard.py 0000664 0000000 0000000 00000012271 13221545743 0030673 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media import MediaMessageProtocolEntity
class VCardMediaMessageProtocolEntity(MediaMessageProtocolEntity):
'''
BEGIN:VCARD
VERSION:3.0
N:Yasser;Hany;;;
FN:Hany Yasser
PHOTO;BASE64:/9j/4AAQSkZJRgABAQEASABIAAD/4QBYRXhpZgAATU0AKgAAAAgAAgESAAMAAAABAAEAAIdpAAQAAAABAAAAJgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAAQKADAAQAAAABAAAAQAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/8AAEQgAQABAAwEiAAIRAQMRAf/EAB8AAAEFAQEBAQEBAAAAAAAAAAABAgMEBQYHCAkKC//EALUQAAIBAwMCBAMFBQQEAAABfQECAwAEEQUSITFBBhNRYQcicRQygZGhCCNCscEVUtHwJDNicoIJChYXGBkaJSYnKCkqNDU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6g4SFhoeIiYqSk5SVlpeYmZqio6Slpqeoqaqys7S1tre4ubrCw8TFxsfIycrS09TV1tfY2drh4uPk5ebn6Onq8fLz9PX29/j5+v/EAB8BAAMBAQEBAQEBAQEAAAAAAAABAgMEBQYHCAkKC//EALURAAIBAgQEAwQHBQQEAAECdwABAgMRBAUhMQYSQVEHYXETIjKBCBRCkaGxwQkjM1LwFWJy0QoWJDThJfEXGBkaJicoKSo1Njc4OTpDREVGR0hJSlNUVVZXWFlaY2RlZmdoaWpzdHV2d3h5eoKDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uLj5OXm5+jp6vLz9PX29/j5+v/bAEMABgYGBgYGCgYGCg4KCgoOEg4ODg4SFxISEhISFxwXFxcXFxccHBwcHBwcHCIiIiIiIicnJycnLCwsLCwsLCwsLP/bAEMBBwcHCwoLEwoKEy4fGh8uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLi4uLv/dAAQABP/aAAwDAQACEQMRAD8A83lPGaqzn/iXgnqZB/WpWbKjNV7kgWC5/wCen9DXix3PoGtCreFJG3OcbVFZmx2XL8A9PoOa9u0b4TDVLH+0tavDZMyBkiUDKqRkGQsQBkc49O9ebeJ9Am8PXX2bzkuYJAWhmjOVcA4Pc4I7jNelCm1BOx5M6kXNpM5VnX77EEn17D6Vt6aVaNtnABxitnwn4DvPEUS3lxIIoH5HG5yPUL059zVTxLoUPhDUYGs7gzRO+yXOCB6A7eOlTUSa5U9SqbcXzNaGdenbYxhevymsPc0rGVyDg9O1a96d9uPT5RWK/C/d6ck0qK0HXd5H/9Dy2U9B2rpPCNgmp6xp9vKgeNJWmdSMgrGN3P44qponhvVvE9ybLSYw8iKXYs21VHTk+56V7B4T8F3nhSKS91gx/anHlxqjbgqty2TgcnA/KvNo0m2n0PYr1oxi431F8R3d7Jef6MbaZ964huDhSCBlsZ5OfXp2rwzxZdyS6rLC0C26xuRhCNrkHbvAHTpivUvEdrdiaWZ4DIXXarrwVJ/oQce9eZXfg3WLgNc22ySNSIzufawc9Bz6116uTucbUYwSRreFb23sLCG6v72RraFjGbVOQwOeo78HjvTtavfDdvpyRWNo4LyIx3sSTg5xz3Hfr9a4n7Bd6bfW9orxSSSyBAqncpYnGDxx161614T8JXet3/8AbXidRHZaVuxDu3FmXLMWPp+XtxQqTk9Be2UYnj94ymFB64zWSxDnJ5UenGas3bmaWRkG1Gdii+iknA/AVQKsoyRwO1ONJxVmTKrGTuj/0e3+D9iLfR5tRZcSXUu0H/ZjxjH4k165fQG4tXRADJ/Dnpn3ri/BVt9h8OaXCMf6lSw772BY/wDoVdm90qSCPHJ6VUI2gkE581RyPNdQQJKVkj3smCpYZYY6Ae+elcT43e78M+F43twI57u4+Y4B25BYgA8cYHNe3ytbtK7lFLttwcc8nHX8K8V+OF5EdK0+BOrXJP4BD/jQkrlTk7aHjPgmztp/E8FxetsgtUluZH7hYULZ+oOK7XQEsNN+G2ra/bNMLu8mNmC8hI2uwwMdCdpJJOTnPSvOdNuPI0/V5lOG+wOg/wC2ksSH9Ca7DXwNH8A6Fpak7rxpL6X6kAL+QJrVLTQwe5545Qc9u1Z104cbe1Pkl3fSqW4szj8qzbLSP//S+ghGIfJjAA2gDHpgY49qZIxN2T2Rf1NULK5XVL66u4+YLaQ20ZH8Tp/rD+BO38DUyzlndWHclT6r2rVkR3KV7eLb3cELIx8zI3DGAM/mcdT6DmvBPjZdfvNLj6bvMfHoOAP0r6JMqujxnoyH9P8A9dfK/wAZrozeILeFOTHbDA9NzMSfyAqLblyZ57arv0vUmzjbbZ/8ixj+ddd8QbxpW0W0PHk6ZASB0G8Fq86ecx2c8Y6SIqn6bg39K6TxS0pv7dpTnNjabfZREuBWqfumdtTmpG2rmqUT/vDnvU07YGKpx4EoySvuKyZZ/9k=
BDAY;value=date:1989-01-05
ORG:Vodafone Egypt;
item1.EMAIL;type=INTERNET:hanyyasser@hotmail.com
item1.X-ABLabel:INTERNET
item2.EMAIL;type=INTERNET:hanybotbot@hotmail.com
item2.X-ABLabel:INTERNET
item3.ADR;type=HOME:;;Heliopolis;Cairo;Al Qahirah;;Egypt
item4.ADR;type=HOME:;;;cairo;;;Egypt
item5.URL:http://www.facebook.com/profile.php?id=626850952
item5.X-ABLabel:_$!!$_
X-FACEBOOK:hany.yasser1
END:VCARD
'''
def __init__(self, name, card_data, _id = None, _from = None, to = None, notify = None, timestamp = None, participant = None,
preview = None, offline = None, retry = None):
super(VCardMediaMessageProtocolEntity, self).__init__("vcard", _id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setVcardMediaProps(name,card_data)
def __str__(self):
out = super(MediaMessageProtocolEntity, self).__str__()
out += "Name: %s\n" % self.name
out += "Card Data: %s\n" % self.card_data
return out
def getName(self):
return self.name
def getCardData(self):
return self.card_data
def setVcardMediaProps(self, name, card_data):
self.name = name
self.card_data = card_data
def toProtocolTreeNode(self):
node = super(VCardMediaMessageProtocolEntity, self).toProtocolTreeNode()
mediaNode = node.getChild("media")
mediaNode["type"] = "vcard"
vcardNode = ProtocolTreeNode("vcard", {"name":self.name}, None,self.card_data)
mediaNode.addChild(vcardNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MediaMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = VCardMediaMessageProtocolEntity
mediaNode = node.getChild("media")
entity.setVcardMediaProps(
mediaNode.getAllChildren()[0].getAttributeValue('name'),
mediaNode.getChild("vcard").getData()
)
return entity yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_iq_requestupload.py 0000664 0000000 0000000 00000001163 13221545743 0031354 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_media.protocolentities import RequestUploadIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class RequestUploadIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(RequestUploadIqProtocolEntityTest, self).setUp()
mediaNode = ProtocolTreeNode("media", {"hash": "hash", "size": "1234", "orighash": "orighash", "type": "image"})
self.ProtocolEntity = RequestUploadIqProtocolEntity
self.node.setAttribute("type", "set")
self.node.addChild(mediaNode) yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_iq_requestupload_result.py 0000664 0000000 0000000 00000001106 13221545743 0032747 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq_result import ResultIqProtocolEntityTest
from yowsup.layers.protocol_media.protocolentities import ResultRequestUploadIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class ResultRequestUploadIqProtocolEntityTest(ResultIqProtocolEntityTest):
def setUp(self):
super(ResultRequestUploadIqProtocolEntityTest, self).setUp()
mediaNode = ProtocolTreeNode("media", {"url": "url", "ip": "1.2.3.4"})
self.ProtocolEntity = ResultRequestUploadIqProtocolEntity
self.node.addChild(mediaNode) yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media.py 0000664 0000000 0000000 00000001066 13221545743 0030553 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.message_media import MediaMessageProtocolEntity
from yowsup.layers.protocol_messages.protocolentities.test_message import MessageProtocolEntityTest
from yowsup.structs import ProtocolTreeNode
class MediaMessageProtocolEntityTest(MessageProtocolEntityTest):
def setUp(self):
super(MediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = MediaMessageProtocolEntity
mediaNode = ProtocolTreeNode("media", {"type":"MEDIA_TYPE"}, None, None)
self.node.addChild(mediaNode)
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable.py 0000664 0000000 0000000 00000001511 13221545743 0033261 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.message_media_downloadable import DownloadableMediaMessageProtocolEntity
from yowsup.layers.protocol_media.protocolentities.test_message_media import MediaMessageProtocolEntityTest
class DownloadableMediaMessageProtocolEntityTest(MediaMessageProtocolEntityTest):
def setUp(self):
super(DownloadableMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = DownloadableMediaMessageProtocolEntity
mediaNode = self.node.getChild("media")
mediaNode.setAttribute("mimetype", "MIMETYPE")
mediaNode.setAttribute("filehash", "FILEHASH")
mediaNode.setAttribute("url", "URL")
mediaNode.setAttribute("ip", "IP")
mediaNode.setAttribute("size", "123")
mediaNode.setAttribute("file", "FILE")
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_audio.py 0000664 0000000 0000000 00000001644 13221545743 0034451 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.message_media_downloadable_audio import AudioDownloadableMediaMessageProtocolEntity
from yowsup.layers.protocol_media.protocolentities.test_message_media_downloadable import DownloadableMediaMessageProtocolEntityTest
class AudioDownloadableMediaMessageProtocolEntityTest(DownloadableMediaMessageProtocolEntityTest):
def setUp(self):
super(AudioDownloadableMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = AudioDownloadableMediaMessageProtocolEntity
mediaNode = self.node.getChild("media")
mediaNode.setAttribute("abitrate", "31")
mediaNode.setAttribute("acodec", "aac")
mediaNode.setAttribute("asampfreq", "22050")
mediaNode.setAttribute("duration", "3")
mediaNode.setAttribute("encoding", "raw")
mediaNode.setAttribute("origin", "live")
mediaNode.setAttribute("seconds", "3")
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_image.py 0000664 0000000 0000000 00000001441 13221545743 0034425 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.message_media_downloadable_image import ImageDownloadableMediaMessageProtocolEntity
from yowsup.layers.protocol_media.protocolentities.test_message_media_downloadable import DownloadableMediaMessageProtocolEntityTest
class ImageDownloadableMediaMessageProtocolEntityTest(DownloadableMediaMessageProtocolEntityTest):
def setUp(self):
super(ImageDownloadableMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = ImageDownloadableMediaMessageProtocolEntity
mediaNode = self.node.getChild("media")
mediaNode.setAttribute("encoding", "ENCODING")
mediaNode.setAttribute("width", "1024")
mediaNode.setAttribute("height", "768")
mediaNode.setAttribute("caption", "caption")
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_video.py 0000664 0000000 0000000 00000002261 13221545743 0034452 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.message_media_downloadable_video import VideoDownloadableMediaMessageProtocolEntity
from yowsup.layers.protocol_media.protocolentities.test_message_media_downloadable import DownloadableMediaMessageProtocolEntityTest
class VideoDownloadableMediaMessageProtocolEntityTest(DownloadableMediaMessageProtocolEntityTest):
def setUp(self):
super(VideoDownloadableMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = VideoDownloadableMediaMessageProtocolEntity
mediaNode = self.node.getChild("media")
mediaNode.setAttribute("abitrate", "165")
mediaNode.setAttribute("acodec", "aac")
mediaNode.setAttribute("asampfmt", "flt")
mediaNode.setAttribute("asampfreq", "48000")
mediaNode.setAttribute("duration", "61")
mediaNode.setAttribute("encoding", "raw")
mediaNode.setAttribute("fps", "24")
mediaNode.setAttribute("height", "452")
mediaNode.setAttribute("seconds", "61")
mediaNode.setAttribute("vbitrate", "1862")
mediaNode.setAttribute("vcodec", "h264")
mediaNode.setAttribute("width", "800")
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_location.py 0000664 0000000 0000000 00000001261 13221545743 0032440 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.test_message_media import MediaMessageProtocolEntityTest
from yowsup.layers.protocol_media.protocolentities import LocationMediaMessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
class LocationMediaMessageProtocolEntityTest(MediaMessageProtocolEntityTest):
def setUp(self):
super(LocationMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = LocationMediaMessageProtocolEntity
mediaNode = self.node.getChild("media")
mediaNode["type"] = "location"
mediaNode["latitude"] = "52.52393"
mediaNode["longitude"] = "13.41747"
mediaNode["encoding"] = "raw"
yowsup-2.5.7/yowsup/layers/protocol_media/protocolentities/test_message_media_vcard.py 0000664 0000000 0000000 00000001235 13221545743 0031730 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_media.protocolentities.test_message_media import MediaMessageProtocolEntityTest
from yowsup.layers.protocol_media.protocolentities import VCardMediaMessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
class VCardMediaMessageProtocolEntityTest(MediaMessageProtocolEntityTest):
def setUp(self):
super(VCardMediaMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = VCardMediaMessageProtocolEntity
vcardNode = ProtocolTreeNode("vcard", {"name":"abc"}, None, "VCARD_DATA")
mediaNode = self.node.getChild("media")
mediaNode["type"] = "vcard"
mediaNode.addChild(vcardNode)
yowsup-2.5.7/yowsup/layers/protocol_messages/ 0000775 0000000 0000000 00000000000 13221545743 0021476 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_messages/__init__.py 0000664 0000000 0000000 00000000054 13221545743 0023606 0 ustar 00root root 0000000 0000000 from .layer import YowMessagesProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_messages/layer.py 0000664 0000000 0000000 00000001421 13221545743 0023162 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import TextMessageProtocolEntity
class YowMessagesProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"message": (self.recvMessageStanza, self.sendMessageEntity)
}
super(YowMessagesProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Messages Layer"
def sendMessageEntity(self, entity):
if entity.getType() == "text":
self.entityToLower(entity)
###recieved node handlers handlers
def recvMessageStanza(self, node):
if node.getAttributeValue("type") == "text":
entity = TextMessageProtocolEntity.fromProtocolTreeNode(node)
self.toUpper(entity)
yowsup-2.5.7/yowsup/layers/protocol_messages/proto/ 0000775 0000000 0000000 00000000000 13221545743 0022641 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_messages/proto/__init__.py 0000664 0000000 0000000 00000000000 13221545743 0024740 0 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_messages/proto/wa.proto 0000664 0000000 0000000 00000003467 13221545743 0024347 0 ustar 00root root 0000000 0000000 package com.whatsapp.proto;
message Message {
optional string conversation = 1;
optional SenderKeyDistributionMessage sender_key_distribution_message = 2;
optional ImageMessage image_message = 3;
optional ContactMessage contact_message = 4;
optional LocationMessage location_message = 5;
optional DocumentMessage document_message = 7;
optional UrlMessage url_message = 6;
}
message SenderKeyDistributionMessage {
required string groupId = 1;
required bytes axolotl_sender_key_distribution_message = 2;
}
message ImageMessage {
required bytes url = 1;
required string mime_type = 2;
required string caption = 3;
required bytes file_sha256 = 4;
required uint64 file_length = 5;
required uint32 height = 6;
required uint32 width = 7;
required bytes media_key = 8;
required bytes jpeg_thumbnail = 16;
}
message LocationMessage {
required double degrees_latitude = 1;
required double degrees_longitude = 2;
required string name = 3;
required string address = 4;
required string url = 5;
required bytes jpeg_thumbnail = 16;
}
message DocumentMessage {
required string url = 1;
required string mimeType = 2;
required string title = 3;
required bytes file_sha256 = 4;
required uint64 file_length = 5;
required uint32 page_count = 6;
required bytes media_key = 7;
required bytes jpeg_thumbnail = 16;
}
message UrlMessage {
required string text = 1;
required string matched_text = 2;
required string canonical_url = 4;
required string description = 5;
required string title = 6;
required string jpeg_thumbnail = 16;
}
message ContactMessage {
required string display_name = 1;
required string vcard = 16;
}
yowsup-2.5.7/yowsup/layers/protocol_messages/proto/wa_pb2.py 0000664 0000000 0000000 00000054754 13221545743 0024404 0 ustar 00root root 0000000 0000000 # Generated by the protocol buffer compiler. DO NOT EDIT!
# source: wa.proto
import sys
_b=sys.version_info[0]<3 and (lambda x:x) or (lambda x:x.encode('latin1'))
from google.protobuf import descriptor as _descriptor
from google.protobuf import message as _message
from google.protobuf import reflection as _reflection
from google.protobuf import symbol_database as _symbol_database
from google.protobuf import descriptor_pb2
# @@protoc_insertion_point(imports)
_sym_db = _symbol_database.Default()
DESCRIPTOR = _descriptor.FileDescriptor(
name='wa.proto',
package='com.whatsapp.proto',
serialized_pb=_b('\n\x08wa.proto\x12\x12\x63om.whatsapp.proto\"\xa3\x03\n\x07Message\x12\x14\n\x0c\x63onversation\x18\x01 \x01(\t\x12Y\n\x1fsender_key_distribution_message\x18\x02 \x01(\x0b\x32\x30.com.whatsapp.proto.SenderKeyDistributionMessage\x12\x37\n\rimage_message\x18\x03 \x01(\x0b\x32 .com.whatsapp.proto.ImageMessage\x12;\n\x0f\x63ontact_message\x18\x04 \x01(\x0b\x32\".com.whatsapp.proto.ContactMessage\x12=\n\x10location_message\x18\x05 \x01(\x0b\x32#.com.whatsapp.proto.LocationMessage\x12=\n\x10\x64ocument_message\x18\x07 \x01(\x0b\x32#.com.whatsapp.proto.DocumentMessage\x12\x33\n\x0burl_message\x18\x06 \x01(\x0b\x32\x1e.com.whatsapp.proto.UrlMessage\"`\n\x1cSenderKeyDistributionMessage\x12\x0f\n\x07groupId\x18\x01 \x02(\t\x12/\n\'axolotl_sender_key_distribution_message\x18\x02 \x02(\x0c\"\xb3\x01\n\x0cImageMessage\x12\x0b\n\x03url\x18\x01 \x02(\x0c\x12\x11\n\tmime_type\x18\x02 \x02(\t\x12\x0f\n\x07\x63\x61ption\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x0e\n\x06height\x18\x06 \x02(\r\x12\r\n\x05width\x18\x07 \x02(\r\x12\x11\n\tmedia_key\x18\x08 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x8a\x01\n\x0fLocationMessage\x12\x18\n\x10\x64\x65grees_latitude\x18\x01 \x02(\x01\x12\x19\n\x11\x64\x65grees_longitude\x18\x02 \x02(\x01\x12\x0c\n\x04name\x18\x03 \x02(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x04 \x02(\t\x12\x0b\n\x03url\x18\x05 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\xa8\x01\n\x0f\x44ocumentMessage\x12\x0b\n\x03url\x18\x01 \x02(\t\x12\x10\n\x08mimeType\x18\x02 \x02(\t\x12\r\n\x05title\x18\x03 \x02(\t\x12\x13\n\x0b\x66ile_sha256\x18\x04 \x02(\x0c\x12\x13\n\x0b\x66ile_length\x18\x05 \x02(\x04\x12\x12\n\npage_count\x18\x06 \x02(\r\x12\x11\n\tmedia_key\x18\x07 \x02(\x0c\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\x0c\"\x83\x01\n\nUrlMessage\x12\x0c\n\x04text\x18\x01 \x02(\t\x12\x14\n\x0cmatched_text\x18\x02 \x02(\t\x12\x15\n\rcanonical_url\x18\x04 \x02(\t\x12\x13\n\x0b\x64\x65scription\x18\x05 \x02(\t\x12\r\n\x05title\x18\x06 \x02(\t\x12\x16\n\x0ejpeg_thumbnail\x18\x10 \x02(\t\"5\n\x0e\x43ontactMessage\x12\x14\n\x0c\x64isplay_name\x18\x01 \x02(\t\x12\r\n\x05vcard\x18\x10 \x02(\t')
)
_sym_db.RegisterFileDescriptor(DESCRIPTOR)
_MESSAGE = _descriptor.Descriptor(
name='Message',
full_name='com.whatsapp.proto.Message',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='conversation', full_name='com.whatsapp.proto.Message.conversation', index=0,
number=1, type=9, cpp_type=9, label=1,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='sender_key_distribution_message', full_name='com.whatsapp.proto.Message.sender_key_distribution_message', index=1,
number=2, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='image_message', full_name='com.whatsapp.proto.Message.image_message', index=2,
number=3, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='contact_message', full_name='com.whatsapp.proto.Message.contact_message', index=3,
number=4, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='location_message', full_name='com.whatsapp.proto.Message.location_message', index=4,
number=5, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='document_message', full_name='com.whatsapp.proto.Message.document_message', index=5,
number=7, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='url_message', full_name='com.whatsapp.proto.Message.url_message', index=6,
number=6, type=11, cpp_type=10, label=1,
has_default_value=False, default_value=None,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=33,
serialized_end=452,
)
_SENDERKEYDISTRIBUTIONMESSAGE = _descriptor.Descriptor(
name='SenderKeyDistributionMessage',
full_name='com.whatsapp.proto.SenderKeyDistributionMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='groupId', full_name='com.whatsapp.proto.SenderKeyDistributionMessage.groupId', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='axolotl_sender_key_distribution_message', full_name='com.whatsapp.proto.SenderKeyDistributionMessage.axolotl_sender_key_distribution_message', index=1,
number=2, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=454,
serialized_end=550,
)
_IMAGEMESSAGE = _descriptor.Descriptor(
name='ImageMessage',
full_name='com.whatsapp.proto.ImageMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='url', full_name='com.whatsapp.proto.ImageMessage.url', index=0,
number=1, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='mime_type', full_name='com.whatsapp.proto.ImageMessage.mime_type', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='caption', full_name='com.whatsapp.proto.ImageMessage.caption', index=2,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='file_sha256', full_name='com.whatsapp.proto.ImageMessage.file_sha256', index=3,
number=4, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='file_length', full_name='com.whatsapp.proto.ImageMessage.file_length', index=4,
number=5, type=4, cpp_type=4, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='height', full_name='com.whatsapp.proto.ImageMessage.height', index=5,
number=6, type=13, cpp_type=3, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='width', full_name='com.whatsapp.proto.ImageMessage.width', index=6,
number=7, type=13, cpp_type=3, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='media_key', full_name='com.whatsapp.proto.ImageMessage.media_key', index=7,
number=8, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='jpeg_thumbnail', full_name='com.whatsapp.proto.ImageMessage.jpeg_thumbnail', index=8,
number=16, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=553,
serialized_end=732,
)
_LOCATIONMESSAGE = _descriptor.Descriptor(
name='LocationMessage',
full_name='com.whatsapp.proto.LocationMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='degrees_latitude', full_name='com.whatsapp.proto.LocationMessage.degrees_latitude', index=0,
number=1, type=1, cpp_type=5, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='degrees_longitude', full_name='com.whatsapp.proto.LocationMessage.degrees_longitude', index=1,
number=2, type=1, cpp_type=5, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='name', full_name='com.whatsapp.proto.LocationMessage.name', index=2,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='address', full_name='com.whatsapp.proto.LocationMessage.address', index=3,
number=4, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='url', full_name='com.whatsapp.proto.LocationMessage.url', index=4,
number=5, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='jpeg_thumbnail', full_name='com.whatsapp.proto.LocationMessage.jpeg_thumbnail', index=5,
number=16, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=735,
serialized_end=873,
)
_DOCUMENTMESSAGE = _descriptor.Descriptor(
name='DocumentMessage',
full_name='com.whatsapp.proto.DocumentMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='url', full_name='com.whatsapp.proto.DocumentMessage.url', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='mimeType', full_name='com.whatsapp.proto.DocumentMessage.mimeType', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='title', full_name='com.whatsapp.proto.DocumentMessage.title', index=2,
number=3, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='file_sha256', full_name='com.whatsapp.proto.DocumentMessage.file_sha256', index=3,
number=4, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='file_length', full_name='com.whatsapp.proto.DocumentMessage.file_length', index=4,
number=5, type=4, cpp_type=4, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='page_count', full_name='com.whatsapp.proto.DocumentMessage.page_count', index=5,
number=6, type=13, cpp_type=3, label=2,
has_default_value=False, default_value=0,
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='media_key', full_name='com.whatsapp.proto.DocumentMessage.media_key', index=6,
number=7, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='jpeg_thumbnail', full_name='com.whatsapp.proto.DocumentMessage.jpeg_thumbnail', index=7,
number=16, type=12, cpp_type=9, label=2,
has_default_value=False, default_value=_b(""),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=876,
serialized_end=1044,
)
_URLMESSAGE = _descriptor.Descriptor(
name='UrlMessage',
full_name='com.whatsapp.proto.UrlMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='text', full_name='com.whatsapp.proto.UrlMessage.text', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='matched_text', full_name='com.whatsapp.proto.UrlMessage.matched_text', index=1,
number=2, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='canonical_url', full_name='com.whatsapp.proto.UrlMessage.canonical_url', index=2,
number=4, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='description', full_name='com.whatsapp.proto.UrlMessage.description', index=3,
number=5, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='title', full_name='com.whatsapp.proto.UrlMessage.title', index=4,
number=6, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='jpeg_thumbnail', full_name='com.whatsapp.proto.UrlMessage.jpeg_thumbnail', index=5,
number=16, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=1047,
serialized_end=1178,
)
_CONTACTMESSAGE = _descriptor.Descriptor(
name='ContactMessage',
full_name='com.whatsapp.proto.ContactMessage',
filename=None,
file=DESCRIPTOR,
containing_type=None,
fields=[
_descriptor.FieldDescriptor(
name='display_name', full_name='com.whatsapp.proto.ContactMessage.display_name', index=0,
number=1, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
_descriptor.FieldDescriptor(
name='vcard', full_name='com.whatsapp.proto.ContactMessage.vcard', index=1,
number=16, type=9, cpp_type=9, label=2,
has_default_value=False, default_value=_b("").decode('utf-8'),
message_type=None, enum_type=None, containing_type=None,
is_extension=False, extension_scope=None,
options=None),
],
extensions=[
],
nested_types=[],
enum_types=[
],
options=None,
is_extendable=False,
extension_ranges=[],
oneofs=[
],
serialized_start=1180,
serialized_end=1233,
)
_MESSAGE.fields_by_name['sender_key_distribution_message'].message_type = _SENDERKEYDISTRIBUTIONMESSAGE
_MESSAGE.fields_by_name['image_message'].message_type = _IMAGEMESSAGE
_MESSAGE.fields_by_name['contact_message'].message_type = _CONTACTMESSAGE
_MESSAGE.fields_by_name['location_message'].message_type = _LOCATIONMESSAGE
_MESSAGE.fields_by_name['document_message'].message_type = _DOCUMENTMESSAGE
_MESSAGE.fields_by_name['url_message'].message_type = _URLMESSAGE
DESCRIPTOR.message_types_by_name['Message'] = _MESSAGE
DESCRIPTOR.message_types_by_name['SenderKeyDistributionMessage'] = _SENDERKEYDISTRIBUTIONMESSAGE
DESCRIPTOR.message_types_by_name['ImageMessage'] = _IMAGEMESSAGE
DESCRIPTOR.message_types_by_name['LocationMessage'] = _LOCATIONMESSAGE
DESCRIPTOR.message_types_by_name['DocumentMessage'] = _DOCUMENTMESSAGE
DESCRIPTOR.message_types_by_name['UrlMessage'] = _URLMESSAGE
DESCRIPTOR.message_types_by_name['ContactMessage'] = _CONTACTMESSAGE
Message = _reflection.GeneratedProtocolMessageType('Message', (_message.Message,), dict(
DESCRIPTOR = _MESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.Message)
))
_sym_db.RegisterMessage(Message)
SenderKeyDistributionMessage = _reflection.GeneratedProtocolMessageType('SenderKeyDistributionMessage', (_message.Message,), dict(
DESCRIPTOR = _SENDERKEYDISTRIBUTIONMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.SenderKeyDistributionMessage)
))
_sym_db.RegisterMessage(SenderKeyDistributionMessage)
ImageMessage = _reflection.GeneratedProtocolMessageType('ImageMessage', (_message.Message,), dict(
DESCRIPTOR = _IMAGEMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.ImageMessage)
))
_sym_db.RegisterMessage(ImageMessage)
LocationMessage = _reflection.GeneratedProtocolMessageType('LocationMessage', (_message.Message,), dict(
DESCRIPTOR = _LOCATIONMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.LocationMessage)
))
_sym_db.RegisterMessage(LocationMessage)
DocumentMessage = _reflection.GeneratedProtocolMessageType('DocumentMessage', (_message.Message,), dict(
DESCRIPTOR = _DOCUMENTMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.DocumentMessage)
))
_sym_db.RegisterMessage(DocumentMessage)
UrlMessage = _reflection.GeneratedProtocolMessageType('UrlMessage', (_message.Message,), dict(
DESCRIPTOR = _URLMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.UrlMessage)
))
_sym_db.RegisterMessage(UrlMessage)
ContactMessage = _reflection.GeneratedProtocolMessageType('ContactMessage', (_message.Message,), dict(
DESCRIPTOR = _CONTACTMESSAGE,
__module__ = 'wa_pb2'
# @@protoc_insertion_point(class_scope:com.whatsapp.proto.ContactMessage)
))
_sym_db.RegisterMessage(ContactMessage)
# @@protoc_insertion_point(module_scope)
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025104 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/__init__.py 0000664 0000000 0000000 00000000230 13221545743 0027210 0 ustar 00root root 0000000 0000000 from .message_text import TextMessageProtocolEntity
from .message import MessageProtocolEntity
from .message_text_broadcast import BroadcastTextMessage
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/message.py 0000664 0000000 0000000 00000010365 13221545743 0027107 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from copy import deepcopy
class MessageProtocolEntity(ProtocolEntity):
MESSAGE_TYPE_TEXT = "text"
MESSAGE_TYPE_MEDIA = "media"
def __init__(self, _type, _id = None, _from = None, to = None, notify = None, timestamp = None,
participant = None, offline = None, retry = None):
assert (to or _from), "Must specify either to or _from jids to create the message"
assert not(to and _from), "Can't set both attributes to message at same time (to, _from)"
super(MessageProtocolEntity, self).__init__("message")
self._type = _type
self._id = self._generateId() if _id is None else _id
self._from =_from
self.to = to
self.timestamp = int(timestamp) if timestamp else self._getCurrentTimestamp()
self.notify = notify
self.offline = offline == "1" if offline is not None else offline
self.retry = int(retry) if retry else None
self.participant = participant
def getType(self):
return self._type
def getId(self):
return self._id
def getTimestamp(self):
return self.timestamp
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def isBroadcast(self):
return False
def getTo(self, full = True):
return self.to if full else self.to.split('@')[0]
def getParticipant(self, full = True):
return self.participant if full else self.participant.split('@')[0]
def getAuthor(self, full = True):
return self.getParticipant(full) if self.isGroupMessage() else self.getFrom(full)
def getNotify(self):
return self.notify
def toProtocolTreeNode(self):
attribs = {
"type" : self._type,
"id" : self._id,
}
if self.isOutgoing():
attribs["to"] = self.to
else:
attribs["from"] = self._from
attribs["t"] = str(self.timestamp)
if self.offline is not None:
attribs["offline"] = "1" if self.offline else "0"
if self.notify:
attribs["notify"] = self.notify
if self.retry:
attribs["retry"] = str(self.retry)
if self.participant:
attribs["participant"] = self.participant
xNode = None
#if self.isOutgoing():
# serverNode = ProtocolTreeNode("server", {})
# xNode = ProtocolTreeNode("x", {"xmlns": "jabber:x:event"}, [serverNode])
return self._createProtocolTreeNode(attribs, children = [xNode] if xNode else None, data = None)
def isOutgoing(self):
return self._from is None
def isGroupMessage(self):
if self.isOutgoing():
return "-" in self.to
return self.participant != None
def __str__(self):
out = "Message:\n"
out += "ID: %s\n" % self._id
out += "To: %s\n" % self.to if self.isOutgoing() else "From: %s\n" % self._from
out += "Type: %s\n" % self._type
out += "Timestamp: %s\n" % self.timestamp
if self.participant:
out += "Participant: %s\n" % self.participant
return out
def ack(self, read=False):
return OutgoingReceiptProtocolEntity(self.getId(), self.getFrom(), read, participant=self.getParticipant())
def forward(self, to, _id = None):
OutgoingMessage = deepcopy(self)
OutgoingMessage.to = to
OutgoingMessage._from = None
OutgoingMessage._id = self._generateId() if _id is None else _id
return OutgoingMessage
@staticmethod
def fromProtocolTreeNode(node):
return MessageProtocolEntity(
node.getAttributeValue("type"),
node.getAttributeValue("id"),
node.getAttributeValue("from"),
node.getAttributeValue("to"),
node.getAttributeValue("notify"),
node.getAttributeValue("t"),
node.getAttributeValue("participant"),
node.getAttributeValue("offline"),
node.getAttributeValue("retry")
)
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/message_text.py 0000664 0000000 0000000 00000002652 13221545743 0030153 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message import MessageProtocolEntity
class TextMessageProtocolEntity(MessageProtocolEntity):
'''
{{MESSAGE_DATA}}
'''
def __init__(self, body, _id = None, _from = None, to = None, notify = None,
timestamp = None, participant = None, offline = None, retry = None):
super(TextMessageProtocolEntity, self).__init__("text",_id, _from, to, notify, timestamp, participant, offline, retry)
self.setBody(body)
def __str__(self):
out = super(TextMessageProtocolEntity, self).__str__()
out += "Body: %s\n" % self.body
return out
def setBody(self, body):
self.body = body
def getBody(self):
return self.body
def toProtocolTreeNode(self):
node = super(TextMessageProtocolEntity, self).toProtocolTreeNode()
bodyNode = ProtocolTreeNode("body", {}, None, self.body)
node.addChild(bodyNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = TextMessageProtocolEntity
entity.setBody(node.getChild("body").getData())
return entity
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/message_text_broadcast.py 0000664 0000000 0000000 00000002241 13221545743 0032167 0 ustar 00root root 0000000 0000000 from .message_text import TextMessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
import time
class BroadcastTextMessage(TextMessageProtocolEntity):
def __init__(self, jids, body):
broadcastTime = int(time.time() * 1000)
super(BroadcastTextMessage, self).__init__(body, to = "%s@broadcast" % broadcastTime)
self.setBroadcastProps(jids)
def setBroadcastProps(self, jids):
assert type(jids) is list, "jids must be a list, got %s instead." % type(jids)
self.jids = jids
def toProtocolTreeNode(self):
node = super(BroadcastTextMessage, self).toProtocolTreeNode()
toNodes = [ProtocolTreeNode("to", {"jid": jid}) for jid in self.jids]
broadcastNode = ProtocolTreeNode("broadcast", children = toNodes)
node.addChild(broadcastNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = TextMessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = BroadcastTextMessage
jids = [toNode.getAttributeValue("jid") for toNode in node.getChild("broadcast").getAllChildren()]
entity.setBroadcastProps(jids)
return entity
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/test_message.py 0000664 0000000 0000000 00000001317 13221545743 0030143 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.protocolentities.message import MessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class MessageProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = MessageProtocolEntity
# ORDER_MATTERS for node.toString() to output return attribs in same order
attribs = {
"type": "message_type",
"id": "message-id",
"t": "12345",
"offline": "0",
"from": "from_jid",
"notify": "notify_name"
}
self.node = ProtocolTreeNode("message", attribs)
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/test_message_text.py 0000664 0000000 0000000 00000001045 13221545743 0031205 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.protocolentities.message_text import TextMessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_messages.protocolentities.test_message import MessageProtocolEntityTest
class TextMessageProtocolEntityTest(MessageProtocolEntityTest):
def setUp(self):
super(TextMessageProtocolEntityTest, self).setUp()
self.ProtocolEntity = TextMessageProtocolEntity
bodyNode = ProtocolTreeNode("body", {}, None, "body_data")
self.node.addChild(bodyNode)
yowsup-2.5.7/yowsup/layers/protocol_messages/protocolentities/test_message_text_broadcast.py 0000664 0000000 0000000 00000001264 13221545743 0033232 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.protocolentities.test_message_text import TextMessageProtocolEntityTest
from yowsup.layers.protocol_messages.protocolentities.message_text_broadcast import BroadcastTextMessage
from yowsup.structs import ProtocolTreeNode
class BroadcastTextMessageTest(TextMessageProtocolEntityTest):
def setUp(self):
super(BroadcastTextMessageTest, self).setUp()
self.ProtocolEntity = BroadcastTextMessage
broadcastNode = ProtocolTreeNode("broadcast")
jids = ["jid1", "jid2"]
toNodes = [ProtocolTreeNode("to", {"jid" : jid}) for jid in jids]
broadcastNode.addChildren(toNodes)
self.node.addChild(broadcastNode)
yowsup-2.5.7/yowsup/layers/protocol_notifications/ 0000775 0000000 0000000 00000000000 13221545743 0022540 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_notifications/__init__.py 0000664 0000000 0000000 00000000060 13221545743 0024645 0 ustar 00root root 0000000 0000000 from .layer import YowNotificationsProtocolLayer yowsup-2.5.7/yowsup/layers/protocol_notifications/layer.py 0000664 0000000 0000000 00000003372 13221545743 0024233 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
class YowNotificationsProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"notification": (self.recvNotification, self.sendNotification)
}
super(YowNotificationsProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "notification Ib Layer"
def sendNotification(self, entity):
if entity.getTag() == "notification":
self.toLower(entity.toProtocolTreeNode())
def recvNotification(self, node):
if node["type"] == "picture":
if node.getChild("set"):
self.toUpper(SetPictureNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node.getChild("delete"):
self.toUpper(DeletePictureNotificationProtocolEntity.fromProtocolTreeNode(node))
else:
self.raiseErrorForNode(node)
elif node["type"] == "status":
self.toUpper(StatusNotificationProtocolEntity.fromProtocolTreeNode(node))
elif node["type"] == "features":
# Not implemented
pass
elif node["type"] in [ "contacts", "subject", "w:gp2" ]:
# Implemented in respectively the protocol_contacts and protocol_groups layer
pass
elif node["type"] == "contacts":
pass
elif node["type"] == "web":
# Not implemented
pass
else:
self.raiseErrorForNode(node)
ack = OutgoingAckProtocolEntity(node["id"], "notification", node["type"], node["from"])
self.toLower(ack.toProtocolTreeNode())
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0026146 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/__init__.py 0000664 0000000 0000000 00000000605 13221545743 0030260 0 ustar 00root root 0000000 0000000 from .notification import NotificationProtocolEntity
from .notification_picture import PictureNotificationProtocolEntity
from .notification_picture_set import SetPictureNotificationProtocolEntity
from .notification_picture_delete import DeletePictureNotificationProtocolEntity
from .notification_status import StatusNotificationProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/notification.py 0000664 0000000 0000000 00000004020 13221545743 0031202 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
class NotificationProtocolEntity(ProtocolEntity):
'''
'''
def __init__(self, _type, _id, _from, timestamp, notify, offline):
super(NotificationProtocolEntity, self).__init__("notification")
self._type = _type
self._id = _id
self._from =_from
self.timestamp = int(timestamp)
self.notify = notify
self.offline = offline == "1"
def __str__(self):
out = "Notification\n"
out += "From: %s\n" % self.getFrom()
out += "Type: %s\n" % self.getType()
return out
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def getType(self):
return self._type
def getId(self):
return self._id
def getTimestamp(self):
return self.timestamp
def toProtocolTreeNode(self):
attribs = {
"t" : str(self.timestamp),
"from" : self._from,
"offline" : "1" if self.offline else "0",
"type" : self._type,
"id" : self._id,
"notify" : self.notify
}
return self._createProtocolTreeNode(attribs, children = None, data = None)
def ack(self):
return OutgoingReceiptProtocolEntity(self.getId(), self.getFrom())
@staticmethod
def fromProtocolTreeNode(node):
return NotificationProtocolEntity(
node.getAttributeValue("type"),
node.getAttributeValue("id"),
node.getAttributeValue("from"),
node.getAttributeValue("t"),
node.getAttributeValue("notify"),
node.getAttributeValue("offline")
)
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/notification_picture.py 0000664 0000000 0000000 00000001457 13221545743 0032750 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .notification import NotificationProtocolEntity
class PictureNotificationProtocolEntity(NotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, status, timestamp, notify, offline, setJid, setId):
super(PictureNotificationProtocolEntity, self).__init__("picture", _id, _from, timestamp, notify, offline)
self.setData(setJid, setId)
@staticmethod
def fromProtocolTreeNode(node):
entity = NotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = PictureNotificationProtocolEntity
return entity yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/notification_picture_delete.py 0000664 0000000 0000000 00000002726 13221545743 0034272 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .notification_picture import PictureNotificationProtocolEntity
class DeletePictureNotificationProtocolEntity(PictureNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, status, timestamp, notify, offline, deleteJid):
super(DeletePictureNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(deleteJid)
def setData(self, deleteJid):
self.deleteJid = deleteJid
def __str__(self):
out = super(DeletePictureNotificationProtocolEntity, self).__str__()
out += "Type: Delete"
return out
def toProtocolTreeNode(self):
node = super(DeletePictureNotificationProtocolEntity, self).toProtocolTreeNode()
deleteNode = ProtocolTreeNode("delete", {"jid": self.deleteJid}, None, None)
node.addChild(deleteNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = DeletePictureNotificationProtocolEntity
deleteNode = node.getChild("delete")
entity.setData(deleteNode.getAttributeValue("jid"))
return entity
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/notification_picture_set.py 0000664 0000000 0000000 00000002575 13221545743 0033625 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .notification_picture import PictureNotificationProtocolEntity
class SetPictureNotificationProtocolEntity(PictureNotificationProtocolEntity):
'''
'''
def __init__(self, _id, _from, status, timestamp, notify, offline, setJid, setId):
super(SetPictureNotificationProtocolEntity, self).__init__(_id, _from, timestamp, notify, offline)
self.setData(setJid, setId)
def setData(self, setJid, setId):
self.setId = setId
self.setJid = setJid
def toProtocolTreeNode(self):
node = super(SetPictureNotificationProtocolEntity, self).toProtocolTreeNode()
setNode = ProtocolTreeNode("set", {"jid": self.setJid, "id": self.setId}, None, None)
node.addChild(setNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureNotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SetPictureNotificationProtocolEntity
setNode = node.getChild("set")
entity.setData(setNode.getAttributeValue("jid"), setNode.getAttributeValue("id"))
return entity yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/notification_status.py 0000664 0000000 0000000 00000002303 13221545743 0032607 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .notification import NotificationProtocolEntity
class StatusNotificationProtocolEntity(NotificationProtocolEntity):
'''
{{STATUS}}
'''
def __init__(self, _type, _id, _from, status, timestamp, notify, offline = False):
super(StatusNotificationProtocolEntity, self).__init__("status", _id, _from, timestamp, notify, offline)
self.setStatus(status)
def setStatus(self, status):
self.status = status
def toProtocolTreeNode(self):
node = super(StatusNotificationProtocolEntity, self).toProtocolTreeNode()
setNode = ProtocolTreeNode("set", {}, None, self.status)
node.addChild(setNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = NotificationProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = StatusNotificationProtocolEntity
entity.setStatus(node.getChild("set").getData())
return entity yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/test_notification.py 0000664 0000000 0000000 00000001226 13221545743 0032246 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_notifications.protocolentities.notification import NotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class NotificationProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = NotificationProtocolEntity
attribs = {
"t": "12345",
"from": "from_jid",
"offline": "0",
"type": "notif_type",
"id": "message-id",
"notify": "notify_name"
}
self.node = ProtocolTreeNode("notification", attribs) yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/test_notification_picture.py 0000664 0000000 0000000 00000000722 13221545743 0034001 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_notifications.protocolentities.notification_picture import PictureNotificationProtocolEntity
from yowsup.layers.protocol_notifications.protocolentities.test_notification import NotificationProtocolEntityTest
class PictureNotificationProtocolEntityTest(NotificationProtocolEntityTest):
def setUp(self):
super(PictureNotificationProtocolEntityTest, self).setUp()
self.ProtocolEntity = PictureNotificationProtocolEntity
test_notification_picture_delete.py 0000664 0000000 0000000 00000001255 13221545743 0035246 0 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities from yowsup.layers.protocol_notifications.protocolentities.notification_picture_delete import DeletePictureNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities.test_notification_picture import PictureNotificationProtocolEntityTest
class DeletePictureNotificationProtocolEntityTest(PictureNotificationProtocolEntityTest):
def setUp(self):
super(DeletePictureNotificationProtocolEntityTest, self).setUp()
self.ProtocolEntity = DeletePictureNotificationProtocolEntity
deleteNode = ProtocolTreeNode("delete", {"jid": "DELETE_JID"}, None, None)
self.node.addChild(deleteNode)
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/test_notification_picture_set.py 0000664 0000000 0000000 00000001237 13221545743 0034656 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_notifications.protocolentities.notification_picture_set import SetPictureNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities.test_notification_picture import PictureNotificationProtocolEntityTest
class SetPictureNotificationProtocolEntityTest(PictureNotificationProtocolEntityTest):
def setUp(self):
super(SetPictureNotificationProtocolEntityTest, self).setUp()
self.ProtocolEntity = SetPictureNotificationProtocolEntity
setNode = ProtocolTreeNode("set", {"jid": "SET_JID", "id": "123"}, None, None)
self.node.addChild(setNode)
yowsup-2.5.7/yowsup/layers/protocol_notifications/protocolentities/test_notification_status.py 0000664 0000000 0000000 00000001136 13221545743 0033651 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_notifications.protocolentities.notification_status import StatusNotificationProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_notifications.protocolentities.test_notification import NotificationProtocolEntityTest
class StatusNotificationProtocolEntityTest(NotificationProtocolEntityTest):
def setUp(self):
super(StatusNotificationProtocolEntityTest, self).setUp()
self.ProtocolEntity = StatusNotificationProtocolEntity
setNode = ProtocolTreeNode("set", {}, [], "status_data")
self.node.addChild(setNode)
yowsup-2.5.7/yowsup/layers/protocol_presence/ 0000775 0000000 0000000 00000000000 13221545743 0021473 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_presence/__init__.py 0000664 0000000 0000000 00000000054 13221545743 0023603 0 ustar 00root root 0000000 0000000 from .layer import YowPresenceProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_presence/layer.py 0000664 0000000 0000000 00000002227 13221545743 0023164 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity
class YowPresenceProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"presence": (self.recvPresence, self.sendPresence),
"iq": (None, self.sendIq)
}
super(YowPresenceProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Presence Layer"
def sendPresence(self, entity):
self.entityToLower(entity)
def recvPresence(self, node):
self.toUpper(PresenceProtocolEntity.fromProtocolTreeNode(node))
def sendIq(self, entity):
if entity.getXmlns() == LastseenIqProtocolEntity.XMLNS:
self._sendIq(entity, self.onLastSeenSuccess, self.onLastSeenError)
def onLastSeenSuccess(self, protocolTreeNode, lastSeenEntity):
self.toUpper(ResultLastseenIqProtocolEntity.fromProtocolTreeNode(protocolTreeNode))
def onLastSeenError(self, protocolTreeNode, lastSeenEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(protocolTreeNode))
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025101 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/__init__.py 0000664 0000000 0000000 00000000710 13221545743 0027210 0 ustar 00root root 0000000 0000000 from .presence import PresenceProtocolEntity
from .presence_available import AvailablePresenceProtocolEntity
from .presence_unavailable import UnavailablePresenceProtocolEntity
from .presence_subscribe import SubscribePresenceProtocolEntity
from .presence_unsubscribe import UnsubscribePresenceProtocolEntity
from .iq_lastseen import LastseenIqProtocolEntity
from .iq_lastseen_result import ResultLastseenIqProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/iq_lastseen.py 0000664 0000000 0000000 00000001307 13221545743 0027763 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.iq import IqProtocolEntity
from yowsup.structs.protocoltreenode import ProtocolTreeNode
class LastseenIqProtocolEntity(IqProtocolEntity):
XMLNS = "jabber:iq:last"
def __init__(self, jid, _id = None):
super(LastseenIqProtocolEntity, self).__init__(self.__class__.XMLNS, _type = "get", to = jid, _id = _id)
@staticmethod
def fromProtocolTreeNode(node):
return LastseenIqProtocolEntity(node["to"])
def toProtocolTreeNode(self):
node = super(LastseenIqProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("xmlns", self.__class__.XMLNS)
node.addChild(ProtocolTreeNode("query"))
return node
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/iq_lastseen_result.py 0000664 0000000 0000000 00000002004 13221545743 0031354 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.iq_result import ResultIqProtocolEntity
from yowsup.structs.protocoltreenode import ProtocolTreeNode
class ResultLastseenIqProtocolEntity(ResultIqProtocolEntity):
def __init__(self, jid, seconds, _id = None):
super(ResultLastseenIqProtocolEntity, self).__init__(_from=jid, _id=_id)
self.setSeconds(seconds)
def setSeconds(self, seconds):
self.seconds = int(seconds)
def getSeconds(self):
return self.seconds
def __str__(self):
out = super(ResultIqProtocolEntity, self).__str__()
out += "Seconds: %s\n" % self.seconds
return out
def toProtocolTreeNode(self):
node = super(ResultLastseenIqProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("query", {"seconds": str(self.seconds)}))
return node
@staticmethod
def fromProtocolTreeNode(node):
return ResultLastseenIqProtocolEntity(node["from"], node.getChild("query")["seconds"], node["id"]) yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/presence.py 0000664 0000000 0000000 00000003611 13221545743 0027260 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class PresenceProtocolEntity(ProtocolEntity):
'''
Should normally be either type or name
when contact goes offline:
when contact goes online:
'''
def __init__(self, _type = None, name = None, _from = None, last = None):
super(PresenceProtocolEntity, self).__init__("presence")
self._type = _type
self.name = name
self._from = _from
self.last = last
def getType(self):
return self._type
def getName(self):
return self.name
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def getLast(self):
return self.last
def toProtocolTreeNode(self):
attribs = {}
if self._type:
attribs["type"] = self._type
if self.name:
attribs["name"] = self.name
if self._from:
attribs["from"] = self._from
if self.last:
attribs["last"] = self.last
return self._createProtocolTreeNode(attribs, None, None)
def __str__(self):
out = "Presence:\n"
if self._type:
out += "Type: %s\n" % self._type
if self.name:
out += "Name: %s\n" % self.name
if self._from:
out += "From: %s\n" % self._from
if self.last:
out += "Last seen: %s\n" % self.last
return out
@staticmethod
def fromProtocolTreeNode(node):
return PresenceProtocolEntity(
node.getAttributeValue("type"),
node.getAttributeValue("name"),
node.getAttributeValue("from"),
node.getAttributeValue("last")
)
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/presence_available.py 0000664 0000000 0000000 00000000603 13221545743 0031256 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .presence import PresenceProtocolEntity
class AvailablePresenceProtocolEntity(PresenceProtocolEntity):
'''
response:
'''
def __init__(self):
super(AvailablePresenceProtocolEntity, self).__init__("available") yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/presence_subscribe.py 0000664 0000000 0000000 00000002011 13221545743 0031312 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .presence import PresenceProtocolEntity
class SubscribePresenceProtocolEntity(PresenceProtocolEntity):
'''
'''
def __init__(self, jid):
super(SubscribePresenceProtocolEntity, self).__init__("subscribe")
self.setProps(jid)
def setProps(self, jid):
self.jid = jid
def toProtocolTreeNode(self):
node = super(SubscribePresenceProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("to", self.jid)
return node
def __str__(self):
out = super(SubscribePresenceProtocolEntity, self).__str__()
out += "To: %s\n" % self.jid
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = PresenceProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SubscribePresenceProtocolEntity
entity.setProps(
node.getAttributeValue("to")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/presence_unavailable.py 0000664 0000000 0000000 00000000635 13221545743 0031626 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .presence import PresenceProtocolEntity
class UnavailablePresenceProtocolEntity(PresenceProtocolEntity):
'''
response:
'''
def __init__(self):
super(UnavailablePresenceProtocolEntity, self).__init__("unavailable") yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/presence_unsubscribe.py 0000664 0000000 0000000 00000002027 13221545743 0031664 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .presence import PresenceProtocolEntity
class UnsubscribePresenceProtocolEntity(PresenceProtocolEntity):
'''
'''
def __init__(self, jid):
super(UnsubscribePresenceProtocolEntity, self).__init__("unsubscribe")
self.setProps(jid)
def setProps(self, jid):
self.jid = jid
def toProtocolTreeNode(self):
node = super(UnsubscribePresenceProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("to", self.jid)
return node
def __str__(self):
out = super(UnsubscribePresenceProtocolEntity, self).__str__()
out += "To: %s\n" % self.jid
return out
@staticmethod
def fromProtocolTreeNode(node):
entity = PresenceProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = UnsubscribePresenceProtocolEntity
entity.setProps(
node.getAttributeValue("to")
)
return entity
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/test_presence.py 0000664 0000000 0000000 00000000733 13221545743 0030321 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_presence.protocolentities.presence import PresenceProtocolEntity
from yowsup.structs import ProtocolTreeNode
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class PresenceProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = PresenceProtocolEntity
self.node = ProtocolTreeNode("presence", {"type": "presence_type", "name": "presence_name"}, None, None)
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/test_presence_available.py 0000664 0000000 0000000 00000000746 13221545743 0032325 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_presence.protocolentities.presence_available import AvailablePresenceProtocolEntity
from yowsup.layers.protocol_presence.protocolentities.test_presence import PresenceProtocolEntityTest
class AvailablePresenceProtocolEntityTest(PresenceProtocolEntityTest):
def setUp(self):
super(AvailablePresenceProtocolEntityTest, self).setUp()
self.ProtocolEntity = AvailablePresenceProtocolEntity
self.node.setAttribute("type", "available")
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/test_presence_subscribe.py 0000664 0000000 0000000 00000001033 13221545743 0032354 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_presence.protocolentities.presence_subscribe import SubscribePresenceProtocolEntity
from yowsup.layers.protocol_presence.protocolentities.test_presence import PresenceProtocolEntityTest
class SubscribePresenceProtocolEntityTest(PresenceProtocolEntityTest):
def setUp(self):
super(SubscribePresenceProtocolEntityTest, self).setUp()
self.ProtocolEntity = SubscribePresenceProtocolEntity
self.node.setAttribute("type", "subscribe")
self.node.setAttribute("to", "subscribe_jid") yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/test_presence_unavailable.py 0000664 0000000 0000000 00000000762 13221545743 0032666 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_presence.protocolentities.presence_unavailable import UnavailablePresenceProtocolEntity
from yowsup.layers.protocol_presence.protocolentities.test_presence import PresenceProtocolEntityTest
class UnavailablePresenceProtocolEntityTest(PresenceProtocolEntityTest):
def setUp(self):
super(UnavailablePresenceProtocolEntityTest, self).setUp()
self.ProtocolEntity = UnavailablePresenceProtocolEntity
self.node.setAttribute("type", "unavailable")
yowsup-2.5.7/yowsup/layers/protocol_presence/protocolentities/test_presence_unsubscribe.py 0000664 0000000 0000000 00000001042 13221545743 0032717 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_presence.protocolentities.presence_unsubscribe import UnsubscribePresenceProtocolEntity
from yowsup.layers.protocol_presence.protocolentities.test_presence import PresenceProtocolEntityTest
class UnsubscribePresenceProtocolEntityTest(PresenceProtocolEntityTest):
def setUp(self):
super(UnsubscribePresenceProtocolEntityTest, self).setUp()
self.ProtocolEntity = UnsubscribePresenceProtocolEntity
self.node.setAttribute("type", "unsubscribe")
self.node.setAttribute("to", "some_jid") yowsup-2.5.7/yowsup/layers/protocol_privacy/ 0000775 0000000 0000000 00000000000 13221545743 0021344 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_privacy/__init__.py 0000664 0000000 0000000 00000000052 13221545743 0023452 0 ustar 00root root 0000000 0000000 from .layer import YowPrivacyProtocolLayer yowsup-2.5.7/yowsup/layers/protocol_privacy/layer.py 0000664 0000000 0000000 00000001027 13221545743 0023032 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
class YowPrivacyProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"iq": (self.recvIq, self.sendIq)
}
super(YowPrivacyProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Privacy Layer"
def sendIq(self, entity):
if entity.getXmlns() == "jabber:iq:privacy":
self.entityToLower(entity)
def recvIq(self, node):
pass
yowsup-2.5.7/yowsup/layers/protocol_privacy/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0024752 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_privacy/protocolentities/__init__.py 0000664 0000000 0000000 00000000067 13221545743 0027066 0 ustar 00root root 0000000 0000000 from .privacylist_iq import PrivacyListIqProtocolEntity yowsup-2.5.7/yowsup/layers/protocol_privacy/protocolentities/privacylist_iq.py 0000664 0000000 0000000 00000001727 13221545743 0030375 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class PrivacyListIqProtocolEntity(IqProtocolEntity):
def __init__(self, name = "default"):
super(PrivacyListIqProtocolEntity, self).__init__("jabber:iq:privacy", _type="get")
self.setListName(name)
def setListName(self, name):
self.listName = name
def toProtocolTreeNode(self):
node = super(PrivacyListIqProtocolEntity, self).toProtocolTreeNode()
queryNode = ProtocolTreeNode("query")
listNode = ProtocolTreeNode("list", {"name": self.listName})
queryNode.addChild(listNode)
node.addChild(queryNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = PrivacyListIqProtocolEntity
entity.setListName(node.getChild("query").getChild("list")["name"])
return entity
yowsup-2.5.7/yowsup/layers/protocol_profiles/ 0000775 0000000 0000000 00000000000 13221545743 0021512 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_profiles/__init__.py 0000664 0000000 0000000 00000000053 13221545743 0023621 0 ustar 00root root 0000000 0000000 from .layer import YowProfilesProtocolLayer yowsup-2.5.7/yowsup/layers/protocol_profiles/layer.py 0000664 0000000 0000000 00000005237 13221545743 0023207 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayer
from .protocolentities import *
from yowsup.layers.protocol_iq.protocolentities import ErrorIqProtocolEntity, ResultIqProtocolEntity
class YowProfilesProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"iq": (self.recvIq, self.sendIq)
}
super(YowProfilesProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Profiles Layer"
def sendIq(self, entity):
if entity.getXmlns() == "w:profile:picture":
if entity.getType() == "get":
self._sendIq(entity, self.onGetPictureResult, self.onGetPictureError)
elif entity.getType() == "set":
self._sendIq(entity, self.onSetPictureResult, self.onSetPictureError)
elif entity.getType() == "delete":
self._sendIq(entity, self.onDeletePictureResult, self.onDeletePictureError)
elif entity.getXmlns() == "status":
self._sendIq(entity, self.onSetStatusResult, self.onSetStatusError)
elif entity.getXmlns() == "privacy":
self._sendIq(entity, self.onPrivacyResult, self.onPrivacyError)
def recvIq(self, node):
pass
def onPrivacyResult(self, resultNode, originIqRequestEntity):
self.toUpper(ResultPrivacyIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onPrivacyError(self, errorNode, originalIqRequestEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
def onSetStatusResult(self, resultNode, originIqRequestEntity):
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onSetStatusError(self, errorNode, originalIqRequestEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
def onGetPictureResult(self, resultNode, originalIqRequestEntity):
self.toUpper(ResultGetPictureIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onGetPictureError(self, errorNode, originalIqRequestEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
def onSetPictureResult(self, resultNode, originalIqRequestEntity):
self.toUpper(ResultGetPictureIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onSetPictureError(self, errorNode, originalIqRequestEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
def onDeletePictureResult(self, resultNode, originalIqRequestEntity):
self.toUpper(ResultIqProtocolEntity.fromProtocolTreeNode(resultNode))
def onDeletePictureError(self, errorNode, originalIqRequestEntity):
self.toUpper(ErrorIqProtocolEntity.fromProtocolTreeNode(errorNode))
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025120 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/__init__.py 0000664 0000000 0000000 00000001003 13221545743 0027223 0 ustar 00root root 0000000 0000000 from .iq_unregister import UnregisterIqProtocolEntity
from .iq_status_set import SetStatusIqProtocolEntity
from .iq_picture_get import GetPictureIqProtocolEntity
from .iq_picture_get_result import ResultGetPictureIqProtocolEntity
from .iq_pictures_list import ListPicturesIqProtocolEntity
from .iq_picture_set import SetPictureIqProtocolEntity
from .iq_privacy_set import SetPrivacyIqProtocolEntity
from .iq_privacy_get import GetPrivacyIqProtocolEntity
from .iq_privacy_result import ResultPrivacyIqProtocolEntity
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_picture.py 0000664 0000000 0000000 00000001036 13221545743 0027636 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
class PictureIqProtocolEntity(IqProtocolEntity):
'''
When receiving a profile picture:
{{Binary bytes of the picture.}}
'''
XMLNS = "w:profile:picture"
def __init__(self, jid, _id = None, type = "get"):
super(PictureIqProtocolEntity, self).__init__(self.__class__.XMLNS, _id = _id, _type=type, to = jid) yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_picture_get.py 0000664 0000000 0000000 00000002216 13221545743 0030476 0 ustar 00root root 0000000 0000000 from .iq_picture import PictureIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class GetPictureIqProtocolEntity(PictureIqProtocolEntity):
'''
'''
def __init__(self, jid, preview = True, _id = None):
super(GetPictureIqProtocolEntity, self).__init__(jid, _id, "get")
self.setGetPictureProps(preview)
def setGetPictureProps(self, preview = True):
self.preview = preview
def isPreview(self):
return self.preview
def toProtocolTreeNode(self):
node = super(GetPictureIqProtocolEntity, self).toProtocolTreeNode()
pictureNode = ProtocolTreeNode("picture", {"type": "preview" if self.isPreview() else "image" })
node.addChild(pictureNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = GetPictureIqProtocolEntity
entity.setGetPictureProps(node.getChild("picture").getAttributeValue("type"))
return entity yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_picture_get_result.py 0000664 0000000 0000000 00000003346 13221545743 0032101 0 ustar 00root root 0000000 0000000 from .iq_picture import PictureIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class ResultGetPictureIqProtocolEntity(PictureIqProtocolEntity):
'''
{{Binary bytes of the picture.}}
'''
def __init__(self, jid, pictureData, pictureId, preview = True, _id = None):
super(ResultGetPictureIqProtocolEntity, self).__init__(jid, _id, "result")
self.setResultPictureProps(pictureData, pictureId, preview)
def setResultPictureProps(self, pictureData, pictureId, preview = True):
self.preview = preview
self.pictureData = pictureData
self.pictureId = pictureId
def isPreview(self):
return self.preview
def getPictureData(self):
return self.pictureData
def getPictureId(self):
return self.pictureId
def writeToFile(self, path):
with open(path, "wb") as outFile:
outFile.write(self.getPictureData())
def toProtocolTreeNode(self):
node = super(ResultGetPictureIqProtocolEntity, self).toProtocolTreeNode()
pictureNode = ProtocolTreeNode({"type": "preview" if self.isPreview() else "image" }, data = self.getPictureData())
node.addChild(pictureNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ResultGetPictureIqProtocolEntity
pictureNode = node.getChild("picture")
entity.setResultPictureProps(pictureNode.getData(), pictureNode.getAttributeValue("id"), pictureNode.getAttributeValue("type") == "preview")
return entity yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_picture_set.py 0000664 0000000 0000000 00000004440 13221545743 0030513 0 ustar 00root root 0000000 0000000 from .iq_picture import PictureIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
import time
class SetPictureIqProtocolEntity(PictureIqProtocolEntity):
'''
{{Binary bytes of the picture when type is set.}}
'''
def __init__(self, jid, previewData, pictureData, pictureId = None, _id = None):
super(SetPictureIqProtocolEntity, self).__init__(jid, _id, "set")
self.setSetPictureProps(previewData, pictureData, pictureId)
def setSetPictureProps(self, previewData, pictureData, pictureId = None):
self.setPictureData(pictureData)
self.setPictureId(pictureId or str(int(time.time())))
self.setPreviewData(previewData)
def setPictureData(self, pictureData):
self.pictureData = pictureData
def getPictureData(self):
return self.pictureData
def setPreviewData(self, previewData):
self.previewData = previewData
def getPreviewData(self):
return self.previewData
def setPictureId(self, pictureId):
self.pictureId = pictureId
def getPictureId(self):
return self.pictureId
def toProtocolTreeNode(self):
node = super(PictureIqProtocolEntity, self).toProtocolTreeNode()
attribs = {"type": "image", "id": self.pictureId}
pictureNode = ProtocolTreeNode("picture", attribs, None, self.getPictureData())
previewNode = ProtocolTreeNode("picture", {"type": "preview"}, None, self.getPreviewData())
node.addChild(pictureNode)
node.addChild(previewNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SetPictureIqProtocolEntity
pictureNode = None
previewNode = None
for child in node.getAllChildren("picture"):
nodeType = child.getAttributeValue("type")
if nodeType == "image":
pictureNode = child
elif nodeType == "preview":
previewNode = child
entity.setSetPictureProps(previewNode.getData(), pictureNode.getData(), pictureNode.getAttributeValue("id"))
return entity yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_pictures_list.py 0000664 0000000 0000000 00000002502 13221545743 0031053 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_picture import PictureIqProtocolEntity
class ListPicturesIqProtocolEntity(PictureIqProtocolEntity):
'''
'''
def __init__(self, selfJid, jids):
super(ListPicturesIqProtocolEntity, self).__init__(jid = selfJid, type = "get")
self.setProps(jids)
def setProps(self, jids):
assert type(jids) is list and len(jids), "Must specify a list of jids to get the pictures for"
self.jids = jids
def toProtocolTreeNode(self):
node = super(ListPicturesIqProtocolEntity, self).toProtocolTreeNode()
userNodes = [ProtocolTreeNode("user", {"jid": jid}) for jid in self.jids]
listNode = ProtocolTreeNode("list", {}, userNodes)
node.addChild(listNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = PictureIqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = ListPicturesIqProtocolEntity
jids = [userNode.getAttributeValue("jid") for userNode in node.getChild("list").getAllChildren()]
entity.setProps(jids)
return entity yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_get.py 0000664 0000000 0000000 00000001627 13221545743 0030505 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
'''
'''
class GetPrivacyIqProtocolEntity(IqProtocolEntity):
XMLNS = "privacy"
def __init__(self):
super(GetPrivacyIqProtocolEntity, self).__init__(self.__class__.XMLNS, _type="get")
def toProtocolTreeNode(self):
node = super(GetPrivacyIqProtocolEntity, self).toProtocolTreeNode()
queryNode = ProtocolTreeNode(self.__class__.XMLNS)
node.addChild(queryNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
assert node.getChild(GetPrivacyIqProtocolEntity.XMLNS) is not None, "Not a get privacy iq node %s" % node
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = GetPrivacyIqProtocolEntity
return entity
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_result.py 0000664 0000000 0000000 00000003267 13221545743 0031246 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
from yowsup.layers.protocol_iq.protocolentities import ResultIqProtocolEntity
'''
'''
class ResultPrivacyIqProtocolEntity(ResultIqProtocolEntity):
NODE_PRIVACY="privacy"
def __init__(self, privacy):
super(ResultPrivacyIqProtocolEntity, self).__init__()
self.setProps(privacy)
def setProps(self, privacy):
assert type(privacy) is dict, "Privacy must be a dict {name => value}"
self.privacy = privacy
def __str__(self):
out = super(ResultPrivacyIqProtocolEntity, self).__str__()
out += "Privacy settings\n"
for name, value in self.privacy.items():
out += "Category %s --> %s\n" % (name, value)
return out
def toProtocolTreeNode(self):
node = super(ResultPrivacyIqProtocolEntity, self).toProtocolTreeNode()
queryNode = ProtocolTreeNode(self.__class__.NODE_PRIVACY)
node.addChild(queryNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = super(ResultPrivacyIqProtocolEntity, ResultPrivacyIqProtocolEntity).fromProtocolTreeNode(node)
entity.__class__ = ResultPrivacyIqProtocolEntity
privacyNode = node.getChild(ResultPrivacyIqProtocolEntity.NODE_PRIVACY)
privacy = {}
for categoryNode in privacyNode.getAllChildren():
privacy[categoryNode["name"]] = categoryNode["value"]
entity.setProps(privacy)
return entity
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_set.py 0000664 0000000 0000000 00000005002 13221545743 0030510 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
'''
'''
class SetPrivacyIqProtocolEntity(IqProtocolEntity):
NAMES = ["status", "profile", "last"]
VALUES = ["all", "contacts", "none"]
XMLNS = "privacy"
def __init__(self, value="all", names = None):
# names can be a string with some element in VALUES or an array with strings with elements in VALUES
# by default, all names are used
super(SetPrivacyIqProtocolEntity, self).__init__(self.__class__.XMLNS, _type="set")
self.setNames(names)
self.setValue(value)
@staticmethod
def checkValidNames(names):
names = names if names else SetPrivacyIqProtocolEntity.NAMES
if not type(names) is list:
names = [names]
for name in names:
if not name in SetPrivacyIqProtocolEntity.NAMES:
raise Exception("Name should be in: '" + "', '".join(SetPrivacyIqProtocolEntity.NAMES) + "' but is '" + name + "'")
return names
@staticmethod
def checkValidValue(value):
if not value in SetPrivacyIqProtocolEntity.VALUES:
raise Exception("Value should be in: '" + "', '".join(SetPrivacyIqProtocolEntity.VALUES) + "' but is '" + value + "'")
return value
def setNames(self, names):
self.names = SetPrivacyIqProtocolEntity.checkValidNames(names)
def setValue(self, value):
self.value = SetPrivacyIqProtocolEntity.checkValidValue(value)
def toProtocolTreeNode(self):
node = super(SetPrivacyIqProtocolEntity, self).toProtocolTreeNode()
queryNode = ProtocolTreeNode(self.__class__.XMLNS)
for name in self.names:
listNode = ProtocolTreeNode("category", {"name": name, "value": self.value})
queryNode.addChild(listNode)
node.addChild(queryNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SetPrivacyIqProtocolEntity
privacyNode = node.getChild(SetPrivacyIqProtocolEntity.XMLNS)
names = []
for categoryNode in privacyNode.getAllChildren():
names.append(categoryNode["name"])
entity.setNames(names)
entity.setValue("all")
return entity
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_status_set.py 0000664 0000000 0000000 00000002177 13221545743 0030370 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class SetStatusIqProtocolEntity(IqProtocolEntity):
'''
{{MSG}}
'''
XMLNS = "status"
def __init__(self, text = None, _id = None):
super(SetStatusIqProtocolEntity, self).__init__(self.__class__.XMLNS, _id, _type = "set", to = YowConstants.WHATSAPP_SERVER)
self.setData(text)
def setData(self, text):
self.text = text
def toProtocolTreeNode(self):
node = super(SetStatusIqProtocolEntity, self).toProtocolTreeNode()
statusNode = ProtocolTreeNode("status", {}, [], self.text)
node.addChild(statusNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = SetStatusIqProtocolEntity
statusNode = node.getChild("status")
entity.setData(statusNode.getData())
return entity
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/iq_unregister.py 0000664 0000000 0000000 00000001734 13221545743 0030357 0 ustar 00root root 0000000 0000000 from yowsup.common import YowConstants
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class UnregisterIqProtocolEntity(IqProtocolEntity):
XMLNS = "urn:xmpp:whatsapp:account"
def __init__(self):
super(UnregisterIqProtocolEntity, self).__init__(_type = "get", to = YowConstants.WHATSAPP_SERVER)
def toProtocolTreeNode(self):
node = super(UnregisterIqProtocolEntity, self).toProtocolTreeNode()
rmNode = ProtocolTreeNode("remove", {"xmlns": self.__class__.XMLNS})
node.addChild(rmNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = IqProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = UnregisterIqProtocolEntity
removeNode = node.getChild("remove")
assert removeNode["xmlns"] == UnregisterIqProtocolEntity.XMLNS, "Not an account delete xmlns, got %s" % removeNode["xmlns"]
return entity yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_get.py 0000664 0000000 0000000 00000000766 13221545743 0031547 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_profiles.protocolentities import GetPrivacyIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
entity = GetPrivacyIqProtocolEntity()
class GetPrivacyIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(GetPrivacyIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = GetPrivacyIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_result.py 0000664 0000000 0000000 00000001070 13221545743 0032273 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_profiles.protocolentities import ResultPrivacyIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
entity = ResultPrivacyIqProtocolEntity({"profile":"all","last":"none","status":"contacts"})
class ResultPrivacyIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(ResultPrivacyIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = ResultPrivacyIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_set.py 0000664 0000000 0000000 00000001030 13221545743 0031544 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_profiles.protocolentities import SetPrivacyIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
entity = SetPrivacyIqProtocolEntity("all", ["profile","last","status"])
class SetPrivacyIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(SetPrivacyIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = SetPrivacyIqProtocolEntity
self.node = entity.toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/test_iq_status_set.py 0000664 0000000 0000000 00000001033 13221545743 0031415 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_profiles.protocolentities import SetStatusIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class SetStatusIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(SetStatusIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = SetStatusIqProtocolEntity
statusNode = ProtocolTreeNode("status", {}, [], "Hey there, I'm using WhatsApp")
self.node.addChild(statusNode)
yowsup-2.5.7/yowsup/layers/protocol_profiles/protocolentities/test_iq_unregister.py 0000664 0000000 0000000 00000000775 13221545743 0031422 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
from yowsup.layers.protocol_profiles.protocolentities import UnregisterIqProtocolEntity
from yowsup.structs import ProtocolTreeNode
class UnregisterIqProtocolEntityTest(IqProtocolEntityTest):
def setUp(self):
super(UnregisterIqProtocolEntityTest, self).setUp()
self.ProtocolEntity = UnregisterIqProtocolEntity
self.node.addChild(ProtocolTreeNode("remove", {"xmlns": "urn:xmpp:whatsapp:account"})) yowsup-2.5.7/yowsup/layers/protocol_receipts/ 0000775 0000000 0000000 00000000000 13221545743 0021505 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_receipts/__init__.py 0000664 0000000 0000000 00000000054 13221545743 0023615 0 ustar 00root root 0000000 0000000 from .layer import YowReceiptProtocolLayer
yowsup-2.5.7/yowsup/layers/protocol_receipts/layer.py 0000664 0000000 0000000 00000001117 13221545743 0023173 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
from .protocolentities import *
class YowReceiptProtocolLayer(YowProtocolLayer):
def __init__(self):
handleMap = {
"receipt": (self.recvReceiptNode, self.sendReceiptEntity)
}
super(YowReceiptProtocolLayer, self).__init__(handleMap)
def __str__(self):
return "Receipt Layer"
def sendReceiptEntity(self, entity):
self.entityToLower(entity)
def recvReceiptNode(self, node):
self.toUpper(IncomingReceiptProtocolEntity.fromProtocolTreeNode(node))
yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/ 0000775 0000000 0000000 00000000000 13221545743 0025113 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/__init__.py 0000664 0000000 0000000 00000000242 13221545743 0027222 0 ustar 00root root 0000000 0000000 from .receipt import ReceiptProtocolEntity
from .receipt_incoming import IncomingReceiptProtocolEntity
from .receipt_outgoing import OutgoingReceiptProtocolEntity yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/receipt.py 0000664 0000000 0000000 00000002033 13221545743 0027116 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class ReceiptProtocolEntity(ProtocolEntity):
'''
delivered:
read
INCOMING
'''
def __init__(self, _id):
super(ReceiptProtocolEntity, self).__init__("receipt")
self._id = _id
def getId(self):
return self._id
def toProtocolTreeNode(self):
attribs = {
"id" : self._id
}
return self._createProtocolTreeNode(attribs, None, data = None)
def __str__(self):
out = "Receipt:\n"
out += "ID: %s\n" % self._id
return out
@staticmethod
def fromProtocolTreeNode(node):
return ReceiptProtocolEntity(
node.getAttributeValue("id")
)
yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/receipt_incoming.py 0000664 0000000 0000000 00000011122 13221545743 0031000 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .receipt import ReceiptProtocolEntity
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
class IncomingReceiptProtocolEntity(ReceiptProtocolEntity):
'''
delivered:
read
delivered to participant in group:
read by participant in group:
multiple items:
multiple items to group:
INCOMING
'''
def __init__(self, _id, _from, timestamp, offline = None, type = None, participant = None, items = None):
super(IncomingReceiptProtocolEntity, self).__init__(_id)
self.setIncomingData(_from, timestamp, offline, type, participant, items)
def getType(self):
return self.type
def getParticipant(self, full=True):
if self.participant:
return self.participant if full else self.participant.split('@')[0]
def getFrom(self, full = True):
return self._from if full else self._from.split('@')[0]
def setIncomingData(self, _from, timestamp, offline, type = None, participant = None, items = None):
self._from = _from
self.timestamp = timestamp
self.type = type
self.participant = participant
if offline is not None:
self.offline = True if offline == "1" else False
else:
self.offline = None
self.items = items
def toProtocolTreeNode(self):
node = super(IncomingReceiptProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("from", self._from)
node.setAttribute("t", str(self.timestamp))
if self.offline is not None:
node.setAttribute("offline", "1" if self.offline else "0")
if self.type is not None:
node.setAttribute("type", self.type)
if self.participant is not None:
node.setAttribute("participant", self.participant)
if self.items is not None:
inodes = []
for item in self.items:
inode = ProtocolTreeNode("item", {"id": item})
inodes.append(inode)
lnode = ProtocolTreeNode("list")
lnode.addChildren(inodes)
node.addChild(lnode)
return node
def __str__(self):
out = super(IncomingReceiptProtocolEntity, self).__str__()
out += "From: %s\n" % self._from
out += "Timestamp: %s\n" % self.timestamp
if self.offline is not None:
out += "Offline: %s\n" % ("1" if self.offline else "0")
if self.type is not None:
out += "Type: %s\n" % (self.type)
if self.participant is not None:
out += "Participant: %s\n" % (self.participant)
if self.items is not None:
out += "Items: %s\n" % " ".join(self.items)
return out
def ack(self):
return OutgoingAckProtocolEntity(self.getId(), "receipt", self.getType(), self.getFrom(), participant = self.participant)
@staticmethod
def fromProtocolTreeNode(node):
items = None
listNode = node.getChild("list")
if listNode is not None:
items = []
for inode in listNode.getAllChildren("item"):
items.append(inode["id"])
return IncomingReceiptProtocolEntity(
node.getAttributeValue("id"),
node.getAttributeValue("from"),
node.getAttributeValue("t"),
node.getAttributeValue("offline"),
node.getAttributeValue("type"),
node.getAttributeValue("participant"),
items
)
yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/receipt_outgoing.py 0000664 0000000 0000000 00000005574 13221545743 0031046 0 ustar 00root root 0000000 0000000 import time
from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .receipt import ReceiptProtocolEntity
class OutgoingReceiptProtocolEntity(ReceiptProtocolEntity):
'''
delivered:
If we send the following without "to" specified, whatsapp will consider the message delivered,
but will not notify the sender.
read
multiple items:
'''
def __init__(self, messageIds, to, read = False, participant = None, callId = None):
if type(messageIds) in (list, tuple):
if len(messageIds) > 1:
receiptId = self._generateId()
else:
receiptId = messageIds[0]
else:
receiptId = messageIds
messageIds = [messageIds]
super(OutgoingReceiptProtocolEntity, self).__init__(receiptId)
self.setOutgoingData(messageIds, to, read, participant, callId)
def setOutgoingData(self, messageIds, to, read, participant, callId):
self.messageIds = messageIds
self.to = to
self.read = read
self.participant = participant
self.callId = callId
def getMessageIds(self):
return self.messageIds
def toProtocolTreeNode(self):
node = super(OutgoingReceiptProtocolEntity, self).toProtocolTreeNode()
if self.read:
node.setAttribute("type", "read")
if self.participant:
node.setAttribute("participant", self.participant)
if self.callId:
offer = ProtocolTreeNode("offer", {"call-id": self.callId})
node.addChild(offer)
node.setAttribute("to", self.to)
if len(self.messageIds) > 1:
listNode = ProtocolTreeNode("list")
listNode.addChildren([ProtocolTreeNode("item", {"id": mId}) for mId in self.messageIds])
node.addChild(listNode)
return node
def __str__(self):
out = super(OutgoingReceiptProtocolEntity, self).__str__()
out += "To: \n%s" % self.to
if self.read:
out += "Type: \n%s" % "read"
out += "For: \n%s" % self.messageIds
return out
@staticmethod
def fromProtocolTreeNode(node):
listNode = node.getChild("list")
messageIds = []
if listNode:
messageIds = [child["id"] for child in listNode.getChildren()]
else:
messageIds = [node["id"]]
return OutgoingReceiptProtocolEntity(
messageIds,
node["to"],
node["type"] == "read",
node["participant"]
)
yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/test_receipt_incoming.py 0000664 0000000 0000000 00000000700 13221545743 0032037 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_receipts.protocolentities import IncomingReceiptProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
import time
class IncomingReceiptProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = IncomingReceiptProtocolEntity
self.node = IncomingReceiptProtocolEntity("123", "sender", int(time.time())).toProtocolTreeNode()
yowsup-2.5.7/yowsup/layers/protocol_receipts/protocolentities/test_receipt_outgoing.py 0000664 0000000 0000000 00000000651 13221545743 0032074 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.structs.protocolentity import ProtocolEntityTest
import unittest
class OutgoingReceiptProtocolEntityTest(ProtocolEntityTest, unittest.TestCase):
def setUp(self):
self.ProtocolEntity = OutgoingReceiptProtocolEntity
self.node = OutgoingReceiptProtocolEntity("123", "target", "read").toProtocolTreeNode() yowsup-2.5.7/yowsup/layers/stanzaregulator/ 0000775 0000000 0000000 00000000000 13221545743 0021173 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/layers/stanzaregulator/__init__.py 0000664 0000000 0000000 00000000045 13221545743 0023303 0 ustar 00root root 0000000 0000000 from .layer import YowStanzaRegulator yowsup-2.5.7/yowsup/layers/stanzaregulator/layer.py 0000664 0000000 0000000 00000003135 13221545743 0022663 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, EventCallback
from yowsup.layers.network import YowNetworkLayer
class YowStanzaRegulator(YowLayer):
'''
send: bytearray -> bytearray
receive: bytearray -> bytearray
'''
def __init__(self):
super(YowStanzaRegulator, self).__init__()
self.buf = bytearray()
self.enabled = False
@EventCallback(YowNetworkLayer.EVENT_STATE_CONNECTED)
def onConnected(self, yowLayerEvent):
self.enabled = True
self.buf = bytearray()
@EventCallback(YowNetworkLayer.EVENT_STATE_DISCONNECTED)
def onDisconnected(self, yowLayerEvent):
self.enabled = False
def send(self, data):
self.toLower(data)
def receive(self, data):
if self.enabled:
self.buf.extend(data)
self.processReceived()
else:
self.toLower(data)
def processReceived(self):
metaData = self.buf[:3]
recvData = self.buf[3:]
firstByte = metaData[0]
stanzaFlag = (firstByte & 0xF0) >> 4
stanzaSize = ((metaData[1] << 8) + metaData[2]) | ((firstByte & 0x0F) << 16)
if len(recvData) < stanzaSize:
#will in leave in buf till receive remaining data
return
oneMessageData = metaData + recvData[:stanzaSize]
self.buf = self.buf[len(oneMessageData):]
self.toUpper(oneMessageData)
if len(self.buf) > 3: #min required if has processable data yet
self.processReceived()
def __str__(self):
return "Stanza Regulator Layer"
yowsup-2.5.7/yowsup/registration/ 0000775 0000000 0000000 00000000000 13221545743 0017161 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/registration/__init__.py 0000664 0000000 0000000 00000000166 13221545743 0021275 0 ustar 00root root 0000000 0000000 from .coderequest import WACodeRequest
from .existsrequest import WAExistsRequest
from .regrequest import WARegRequest yowsup-2.5.7/yowsup/registration/coderequest.py 0000664 0000000 0000000 00000004734 13221545743 0022066 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
from yowsup.common.tools import StorageTools, WATools
from yowsup.registration.existsrequest import WAExistsRequest
from yowsup.env import YowsupEnv
import random, hashlib, os
class WACodeRequest(WARequest):
def __init__(self,cc, p_in, mcc= "000", mnc = "000", sim_mcc = "000", sim_mnc = "000", method="sms"):
super(WACodeRequest,self).__init__()
idx = StorageTools.getIdentity(cc + p_in)
self.p_in = p_in
self.__id = idx
self.cc = cc
self.addParam("cc", cc)
self.addParam("in", p_in)
self.addParam("lc", "GB")
self.addParam("lg", "en")
self.addParam("sim_mcc", sim_mcc.zfill(3))
self.addParam("sim_mnc", sim_mnc.zfill(3))
self.addParam("mcc", sim_mcc.zfill(3))
self.addParam("mnc", sim_mnc.zfill(3))
self.addParam("method", method)
self.addParam("mistyped", "6")
self.addParam("network_radio_type", "1")
self.addParam("simnum", "1")
self.addParam("s", "")
self.addParam("copiedrc", "1")
self.addParam("hasinrc", "1")
self.addParam("rcmatch", "1")
self.addParam("pid", int(random.uniform(100,9999)))
self.addParam("rchash", hashlib.sha256(os.urandom(20)).hexdigest())
self.addParam("anhash", os.urandom(20))
self.addParam("extexist", "1")
self.addParam("extstate", "1")
self.addParam("token", YowsupEnv.getCurrent().getToken(p_in))
self.url = "v.whatsapp.net/v2/code"
self.pvars = ["status","reason","length", "method", "retry_after", "code", "param"] +\
["login", "pw", "type", "expiration", "kind", "price", "cost", "currency", "price_expiration"]
self.setParser(JSONResponseParser())
def send(self, parser = None):
if self.__id is not None:
request = WAExistsRequest(self.cc, self.p_in, self.__id)
result = request.send()
if result["status"] == "ok":
return result
elif result["status"] == "fail" and "reason" in result and result["reason"] == "blocked":
return result
self.__id = WATools.generateIdentity()
self.addParam("id", self.__id)
res = super(WACodeRequest, self).send(parser)
if res["status"] == "sent":
StorageTools.writeIdentity(self.cc + self.p_in, self.__id)
return res
yowsup-2.5.7/yowsup/registration/existsrequest.py 0000664 0000000 0000000 00000002474 13221545743 0022472 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
from yowsup.env import YowsupEnv
import os
class WAExistsRequest(WARequest):
def __init__(self,cc, p_in, idx):
super(WAExistsRequest,self).__init__()
self.addParam("cc", cc)
self.addParam("in", p_in)
self.addParam("id", idx)
self.addParam("lg", "en")
self.addParam("lc", "GB")
self.addParam("token", YowsupEnv.getCurrent().getToken(p_in))
self.addParam("mistyped", '6')
self.addParam('network_radio_type', '1')
self.addParam('simnum', '1')
self.addParam('s', '')
self.addParam('copiedrc', '1')
self.addParam('hasinrc', '1')
self.addParam('rcmatch', '1')
self.addParam('pid', os.getpid())
self.addParam('extexist', '1')
self.addParam('extstate', '1')
self.url = "v.whatsapp.net/v2/exist"
self.pvars = ["status", "reason", "sms_length", "voice_length", "result","param", "pw", "login", "type", "expiration", "kind",
"price", "cost", "currency", "price_expiration"
]
self.setParser(JSONResponseParser())
def send(self, parser = None):
res = super(WAExistsRequest, self).send(parser)
return res
yowsup-2.5.7/yowsup/registration/regrequest.py 0000664 0000000 0000000 00000005051 13221545743 0021722 0 ustar 00root root 0000000 0000000 '''
Copyright (c) <2012> Tarek Galal
Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR
A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
'''
from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
from yowsup.common.tools import StorageTools
import hashlib
import os
class WARegRequest(WARequest):
def __init__(self,cc, p_in, code):
super(WARegRequest,self).__init__()
idx = StorageTools.getIdentity(cc + p_in)
if idx is None:
raise ValueError("You have to request code first")
self.addParam("cc", cc)
self.addParam("in", p_in)
self.addParam("id", idx)
self.addParam("code", code)
self.addParam("lc", "GB")
self.addParam("lg", "en")
self.addParam("mistyped", '6')
# self.addParam('network_radio_type', '1')
self.addParam('simnum', '1')
self.addParam('s', '')
self.addParam('copiedrc', '1')
self.addParam('hasinrc', '1')
self.addParam('rcmatch', '1')
self.addParam('pid', os.getpid())
self.addParam('rchash', hashlib.sha256(os.urandom(20)).hexdigest())
self.addParam('anhash', hashlib.md5(os.urandom(20)).hexdigest())
self.addParam('extexist', '1')
self.addParam('extstate', '1')
self.url = "v.whatsapp.net/v2/register"
self.pvars = ["status", "login", "pw", "type", "expiration", "kind", "price", "cost", "currency", "price_expiration",
"reason","retry_after"]
self.setParser(JSONResponseParser())
def register(self):
return self.send()
yowsup-2.5.7/yowsup/stacks/ 0000775 0000000 0000000 00000000000 13221545743 0015737 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/stacks/__init__.py 0000664 0000000 0000000 00000005114 13221545743 0020051 0 ustar 00root root 0000000 0000000 from .yowstack import YowStack, YowStackBuilder
from yowsup.layers.auth import YowCryptLayer, YowAuthenticationProtocolLayer, AuthError
from yowsup.layers.coder import YowCoderLayer
from yowsup.layers.logger import YowLoggerLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer
from yowsup.layers.stanzaregulator import YowStanzaRegulator
from yowsup.layers.protocol_media import YowMediaProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_groups import YowGroupsProtocolLayer
from yowsup.layers.protocol_presence import YowPresenceProtocolLayer
from yowsup.layers.protocol_ib import YowIbProtocolLayer
from yowsup.layers.protocol_notifications import YowNotificationsProtocolLayer
from yowsup.layers.protocol_iq import YowIqProtocolLayer
from yowsup.layers.protocol_contacts import YowContactsIqProtocolLayer
from yowsup.layers.protocol_chatstate import YowChatstateProtocolLayer
from yowsup.layers.protocol_privacy import YowPrivacyProtocolLayer
from yowsup.layers.protocol_profiles import YowProfilesProtocolLayer
from yowsup.layers.protocol_calls import YowCallsProtocolLayer
YOWSUP_CORE_LAYERS = (
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
YOWSUP_PROTOCOL_LAYERS_BASIC = (
YowAuthenticationProtocolLayer, YowMessagesProtocolLayer,
YowReceiptProtocolLayer, YowAckProtocolLayer, YowPresenceProtocolLayer,
YowIbProtocolLayer, YowIqProtocolLayer, YowNotificationsProtocolLayer,
YowContactsIqProtocolLayer, YowChatstateProtocolLayer
)
YOWSUP_PROTOCOL_LAYERS_GROUPS = (YowGroupsProtocolLayer,) + YOWSUP_PROTOCOL_LAYERS_BASIC
YOWSUP_PROTOCOL_LAYERS_MEDIA = (YowMediaProtocolLayer,) + YOWSUP_PROTOCOL_LAYERS_BASIC
YOWSUP_PROTOCOL_LAYERS_PROFILES = (YowProfilesProtocolLayer,) + YOWSUP_PROTOCOL_LAYERS_BASIC
YOWSUP_PROTOCOL_LAYERS_CALLS = (YowCallsProtocolLayer,) + YOWSUP_PROTOCOL_LAYERS_BASIC
YOWSUP_PROTOCOL_LAYERS_FULL = (YowGroupsProtocolLayer, YowMediaProtocolLayer, YowPrivacyProtocolLayer, YowProfilesProtocolLayer, YowCallsProtocolLayer)\
+ YOWSUP_PROTOCOL_LAYERS_BASIC
YOWSUP_FULL_STACK = (YOWSUP_PROTOCOL_LAYERS_FULL,) +\
YOWSUP_CORE_LAYERS
yowsup-2.5.7/yowsup/stacks/yowstack.py 0000664 0000000 0000000 00000021012 13221545743 0020151 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowParallelLayer
import asyncore, time, logging, random
from yowsup.layers import YowLayer
from yowsup.layers.auth import YowCryptLayer, YowAuthenticationProtocolLayer
from yowsup.layers.coder import YowCoderLayer
from yowsup.layers.logger import YowLoggerLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer
from yowsup.layers.stanzaregulator import YowStanzaRegulator
from yowsup.layers.protocol_media import YowMediaProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_groups import YowGroupsProtocolLayer
from yowsup.layers.protocol_presence import YowPresenceProtocolLayer
from yowsup.layers.protocol_ib import YowIbProtocolLayer
from yowsup.layers.protocol_notifications import YowNotificationsProtocolLayer
from yowsup.layers.protocol_iq import YowIqProtocolLayer
from yowsup.layers.protocol_contacts import YowContactsIqProtocolLayer
from yowsup.layers.protocol_chatstate import YowChatstateProtocolLayer
from yowsup.layers.protocol_privacy import YowPrivacyProtocolLayer
from yowsup.layers.protocol_profiles import YowProfilesProtocolLayer
from yowsup.layers.protocol_calls import YowCallsProtocolLayer
from yowsup.env import YowsupEnv
from yowsup.common.constants import YowConstants
import inspect
try:
import Queue
except ImportError:
import queue as Queue
logger = logging.getLogger(__name__)
YOWSUP_PROTOCOL_LAYERS_BASIC = (
YowAuthenticationProtocolLayer, YowMessagesProtocolLayer,
YowReceiptProtocolLayer, YowAckProtocolLayer, YowPresenceProtocolLayer,
YowIbProtocolLayer, YowIqProtocolLayer, YowNotificationsProtocolLayer,
YowContactsIqProtocolLayer, YowChatstateProtocolLayer, YowCallsProtocolLayer
)
class YowStackBuilder(object):
def __init__(self):
self.layers = ()
self._props = {}
def setProp(self, key, value):
self._props[key] = value
return self
def pushDefaultLayers(self, axolotl = False):
defaultLayers = YowStackBuilder.getDefaultLayers(axolotl)
self.layers += defaultLayers
return self
def push(self, yowLayer):
self.layers += (yowLayer,)
return self
def pop(self):
self.layers = self.layers[:-1]
return self
def build(self):
return YowStack(self.layers, reversed = False, props = self._props)
@staticmethod
def getDefaultLayers(axolotl = False, groups = True, media = True, privacy = True, profiles = True):
coreLayers = YowStackBuilder.getCoreLayers()
protocolLayers = YowStackBuilder.getProtocolLayers(groups = groups, media=media, privacy=privacy, profiles=profiles)
allLayers = coreLayers
if axolotl:
from yowsup.layers.axolotl import AxolotlSendLayer, AxolotlControlLayer, AxolotlReceivelayer
allLayers += (AxolotlControlLayer,)
allLayers += (YowParallelLayer((AxolotlSendLayer, AxolotlReceivelayer)),)
allLayers += (YowParallelLayer(protocolLayers),)
return allLayers
@staticmethod
def getDefaultStack(layer = None, axolotl = False, groups = True, media = True, privacy = True, profiles = True):
"""
:param layer: An optional layer to put on top of default stack
:param axolotl: E2E encryption enabled/ disabled
:return: YowStack
"""
allLayers = YowStackBuilder.getDefaultLayers(axolotl, groups = groups, media=media,privacy=privacy, profiles=profiles)
if layer:
allLayers = allLayers + (layer,)
return YowStack(allLayers, reversed = False)
@staticmethod
def getCoreLayers():
return (
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)[::-1]
@staticmethod
def getProtocolLayers(groups = True, media = True, privacy = True, profiles = True):
layers = YOWSUP_PROTOCOL_LAYERS_BASIC
if groups:
layers += (YowGroupsProtocolLayer,)
if media:
layers += (YowMediaProtocolLayer, )
if privacy:
layers += (YowPrivacyProtocolLayer, )
if profiles:
layers += (YowProfilesProtocolLayer, )
return layers
class YowStack(object):
__stack = []
__stackInstances = []
__detachedQueue = Queue.Queue()
def __init__(self, stackClassesArr = None, reversed = True, props = None):
stackClassesArr = stackClassesArr or ()
self.__stack = stackClassesArr[::-1] if reversed else stackClassesArr
self.__stackInstances = []
self._props = props or {}
self.setProp(YowNetworkLayer.PROP_ENDPOINT, YowConstants.ENDPOINTS[random.randint(0,len(YowConstants.ENDPOINTS)-1)])
self.setProp(YowCoderLayer.PROP_DOMAIN, YowConstants.DOMAIN)
self.setProp(YowCoderLayer.PROP_RESOURCE, YowsupEnv.getCurrent().getResource())
self._construct()
def getLayerInterface(self, YowLayerClass):
for inst in self.__stackInstances:
if inst.__class__ == YowLayerClass:
return inst.getLayerInterface()
elif inst.__class__ == YowParallelLayer:
res = inst.getLayerInterface(YowLayerClass)
if res:
return res
def send(self, data):
self.__stackInstances[-1].send(data)
def receive(self, data):
self.__stackInstances[0].receive(data)
def setCredentials(self, credentials):
self.getLayerInterface(YowAuthenticationProtocolLayer).setCredentials(*credentials)
def addLayer(self, layerClass):
self.__stack.push(layerClass)
def addPostConstructLayer(self, layer):
self.__stackInstances[-1].setLayers(layer, self.__stackInstances[-2])
layer.setLayers(None, self.__stackInstances[-1])
self.__stackInstances.append(layer)
def setProp(self, key, value):
self._props[key] = value
def getProp(self, key, default = None):
return self._props[key] if key in self._props else default
def emitEvent(self, yowLayerEvent):
if not self.__stackInstances[0].onEvent(yowLayerEvent):
self.__stackInstances[0].emitEvent(yowLayerEvent)
def broadcastEvent(self, yowLayerEvent):
if not self.__stackInstances[-1].onEvent(yowLayerEvent):
self.__stackInstances[-1].broadcastEvent(yowLayerEvent)
def execDetached(self, fn):
self.__class__.__detachedQueue.put(fn)
def loop(self, *args, **kwargs):
if "discrete" in kwargs:
discreteVal = kwargs["discrete"]
del kwargs["discrete"]
while True:
asyncore.loop(*args, **kwargs)
time.sleep(discreteVal)
try:
callback = self.__class__.__detachedQueue.get(False) #doesn't block
callback()
except Queue.Empty:
pass
else:
asyncore.loop(*args, **kwargs)
def _construct(self):
logger.debug("Initializing stack")
for s in self.__stack:
if type(s) is tuple:
logger.warn("Implicit declaration of parallel layers in a tuple is deprecated, pass a YowParallelLayer instead")
inst = YowParallelLayer(s)
else:
if inspect.isclass(s):
if issubclass(s, YowLayer):
inst = s()
else:
raise ValueError("Stack must contain only subclasses of YowLayer")
elif issubclass(s.__class__, YowLayer):
inst = s
else:
raise ValueError("Stack must contain only subclasses of YowLayer")
#inst = s()
logger.debug("Constructed %s" % inst)
inst.setStack(self)
self.__stackInstances.append(inst)
for i in range(0, len(self.__stackInstances)):
upperLayer = self.__stackInstances[i + 1] if (i + 1) < len(self.__stackInstances) else None
lowerLayer = self.__stackInstances[i - 1] if i > 0 else None
self.__stackInstances[i].setLayers(upperLayer, lowerLayer)
def getLayer(self, layerIndex):
return self.__stackInstances[layerIndex]
yowsup-2.5.7/yowsup/structs/ 0000775 0000000 0000000 00000000000 13221545743 0016156 5 ustar 00root root 0000000 0000000 yowsup-2.5.7/yowsup/structs/__init__.py 0000664 0000000 0000000 00000000131 13221545743 0020262 0 ustar 00root root 0000000 0000000 from .protocolentity import ProtocolEntity
from .protocoltreenode import ProtocolTreeNode yowsup-2.5.7/yowsup/structs/protocolentity.py 0000664 0000000 0000000 00000002702 13221545743 0021627 0 ustar 00root root 0000000 0000000 from .protocoltreenode import ProtocolTreeNode
import unittest, time
class ProtocolEntity(object):
__ID_GEN = 0
def __init__(self, tag):
self.tag = tag
def getTag(self):
return self.tag
def isType(self, typ):
return self.tag == typ
def _createProtocolTreeNode(self, attributes, children = None, data = None):
return ProtocolTreeNode(self.getTag(), attributes, children, data)
def _getCurrentTimestamp(self):
return int(time.time())
def _generateId(self, short = False):
ProtocolEntity.__ID_GEN += 1
return str(ProtocolEntity.__ID_GEN) if short else str(int(time.time())) + "-" + str(ProtocolEntity.__ID_GEN)
def toProtocolTreeNode(self):
pass
@staticmethod
def fromProtocolTreeNode(self, protocolTreeNode):
pass
class ProtocolEntityTest(object):
def setUp(self):
self.ProtocolEntity = None
self.node = None
# def assertEqual(self, entity, node):
# raise AssertionError("Should never execute that")
def test_generation(self):
if self.ProtocolEntity is None:
raise ValueError("Test case not setup!")
entity = self.ProtocolEntity.fromProtocolTreeNode(self.node)
try:
self.assertEqual(entity.toProtocolTreeNode(), self.node)
except:
print(entity.toProtocolTreeNode())
print("\nNOTEQ\n")
print(self.node)
raise
yowsup-2.5.7/yowsup/structs/protocoltreenode.py 0000664 0000000 0000000 00000011262 13221545743 0022121 0 ustar 00root root 0000000 0000000 import binascii
import sys
class ProtocolTreeNode(object):
def __init__(self, tag, attributes = None, children = None, data = None):
self.tag = tag
self.attributes = attributes or {}
self.children = children or []
self.data = data
assert type(self.children) is list, "Children must be a list, got %s" % type(self.children)
def __eq__(self, protocolTreeNode):
"""
:param protocolTreeNode: ProtocolTreeNode
:return: bool
"""
#
if protocolTreeNode.__class__ == ProtocolTreeNode\
and self.tag == protocolTreeNode.tag\
and self.data == protocolTreeNode.data\
and self.attributes == protocolTreeNode.attributes\
and len(self.getAllChildren()) == len(protocolTreeNode.getAllChildren()):
found = False
for c in self.getAllChildren():
for c2 in protocolTreeNode.getAllChildren():
if c == c2:
found = True
break
if not found:
return False
found = False
for c in protocolTreeNode.getAllChildren():
for c2 in self.getAllChildren():
if c == c2:
found = True
break
if not found:
return False
return True
return False
def __hash__(self):
return hash(self.tag) ^ hash(tuple(self.attributes.items())) ^ hash(self.data)
def toString(self):
out = "<"+self.tag
if self.attributes is not None:
for key,val in self.attributes.items():
if val is None:
raise ValueError("value is none for attr %s" % key)
out+= " "+key+'="'+val+'"'
out+= ">\n"
if self.data is not None:
if type(self.data) is bytearray:
try:
out += "%s" % self.data.decode()
except UnicodeDecodeError:
out += binascii.hexlify(self.data)
else:
try:
out += "%s" % self.data
except UnicodeDecodeError:
try:
out += "%s" % self.data.decode()
except UnicodeDecodeError:
out += binascii.hexlify(self.data)
if type(self.data) is str and sys.version_info >= (3,0):
out += "\nHEX3:%s\n" % binascii.hexlify(self.data.encode('latin-1'))
else:
out += "\nHEX:%s\n" % binascii.hexlify(self.data)
for c in self.children:
try:
out += c.toString()
except UnicodeDecodeError:
out += "[ENCODED DATA]\n"
out+= ""+self.tag+">\n"
return out
def __str__(self):
return self.toString()
def getData(self):
return self.data
def setData(self, data):
self.data = data
@staticmethod
def tagEquals(node,string):
return node is not None and node.tag is not None and node.tag == string
@staticmethod
def require(node,string):
if not ProtocolTreeNode.tagEquals(node,string):
raise Exception("failed require. string: "+string);
def __getitem__(self, key):
return self.getAttributeValue(key)
def __setitem__(self, key, val):
self.setAttribute(key, val)
def __delitem__(self, key):
self.removeAttribute(key)
def getChild(self,identifier):
if type(identifier) == int:
if len(self.children) > identifier:
return self.children[identifier]
else:
return None
for c in self.children:
if identifier == c.tag:
return c
return None
def hasChildren(self):
return len(self.children) > 0
def addChild(self, childNode):
self.children.append(childNode)
def addChildren(self, children):
for c in children:
self.addChild(c)
def getAttributeValue(self,string):
try:
return self.attributes[string]
except KeyError:
return None
def removeAttribute(self, key):
if key in self.attributes:
del self.attributes[key]
def setAttribute(self, key, value):
self.attributes[key] = value
def getAllChildren(self,tag = None):
ret = []
if tag is None:
return self.children
for c in self.children:
if tag == c.tag:
ret.append(c)
return ret