pax_global_header 0000666 0000000 0000000 00000000064 12633464636 0014527 g ustar 00root root 0000000 0000000 52 comment=a59ac410c057e8042c528e9f73e9f3eaada6e79e
yowsup-2.4.48/ 0000775 0000000 0000000 00000000000 12633464636 0013174 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/.gitignore 0000664 0000000 0000000 00000000070 12633464636 0015161 0 ustar 00root root 0000000 0000000 *.pyc
*.class
todo
*.egg-info
tp
tests
dist
build
.idea
yowsup-2.4.48/.travis.yml 0000664 0000000 0000000 00000000374 12633464636 0015311 0 ustar 00root root 0000000 0000000 language: python
python:
- "2.6"
- "2.7"
- "3.2"
- "3.3"
- "3.4"
# command to install dependencies
install:
- python setup.py install
# command to run tests
script: nosetests
branches:
only:
- master
- develop
- uniform_xml
yowsup-2.4.48/LICENSE 0000664 0000000 0000000 00000104462 12633464636 0014210 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.4.48/README.md 0000664 0000000 0000000 00000007230 12633464636 0014455 0 ustar 00root root 0000000 0000000 # Yowsup 2 [](https://travis-ci.org/tgalal/yowsup)
## Updates (December 14, 2015)
Yowsup v2.4.48 is out, See [release notes](https://github.com/tgalal/yowsup/releases/tag/v2.4.48)
==========================================================
## Yowsup opened WhatsApp service under platforms!
Yowsup is a python library that enables you build application which use WhatsApp service. Yowsup has been used to create an unofficial WhatsApp client Nokia N9 through the Wazapp project which was in use by 200K + users as well as 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 using pip:
```
pip install yowsup2
```
### Linux
You need to have installed python headers (from probably 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.
### 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.4.48/setup.py 0000775 0000000 0000000 00000002543 12633464636 0014715 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
deps = ['python-dateutil', 'argparse', 'python-axolotl>=0.1.7', 'pillow']
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,
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.4.48/yowsup-cli 0000775 0000000 0000000 00000031616 12633464636 0015244 0 ustar 00root root 0000000 0000000 #!/usr/bin/env python
__version__ = "2.0.13"
__author__ = "Tarek Galal"
import sys, argparse, yowsup, logging
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==
#######################################################
"""
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["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)
if self.args["debug"]:
logging.basicConfig(level = logging.DEBUG)
else:
logging.basicConfig(level = logging.INFO)
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("-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/help/telephone-country-codes.htm. 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["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
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
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("-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["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)
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:
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:
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:
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.4.48/yowsup/ 0000775 0000000 0000000 00000000000 12633464636 0014542 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/__init__.py 0000664 0000000 0000000 00000000062 12633464636 0016651 0 ustar 00root root 0000000 0000000 __version__ = "2.4.48"
__author__ = "Tarek Galal"
yowsup-2.4.48/yowsup/common/ 0000775 0000000 0000000 00000000000 12633464636 0016032 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/common/__init__.py 0000664 0000000 0000000 00000000043 12633464636 0020140 0 ustar 00root root 0000000 0000000 from .constants import YowConstants yowsup-2.4.48/yowsup/common/constants.py 0000664 0000000 0000000 00000001317 12633464636 0020422 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),
)
PATH_STORAGE = "~/.yowsup"
PREVIEW_WIDTH = 64
PREVIEW_HEIGHT = 64
yowsup-2.4.48/yowsup/common/http/ 0000775 0000000 0000000 00000000000 12633464636 0017011 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/common/http/__init__.py 0000664 0000000 0000000 00000000162 12633464636 0021121 0 ustar 00root root 0000000 0000000 from .httpproxy import HttpProxy
from .warequest import WARequest
from .waresponseparser import JSONResponseParser yowsup-2.4.48/yowsup/common/http/httpproxy.py 0000664 0000000 0000000 00000006323 12633464636 0021450 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.4.48/yowsup/common/http/test_warequest.py 0000664 0000000 0000000 00000000062 12633464636 0022440 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest yowsup-2.4.48/yowsup/common/http/warequest.py 0000664 0000000 0000000 00000011005 12633464636 0021400 0 ustar 00root root 0000000 0000000 import urllib,sys, os, logging
import hashlib
from .waresponseparser import ResponseParser
from yowsup.env import S40YowsupEnv
CURRENT_ENV = S40YowsupEnv()
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 CURRENT_ENV.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.4.48/yowsup/common/http/waresponseparser.py 0000664 0000000 0000000 00000010320 12633464636 0022762 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.4.48/yowsup/common/tools.py 0000664 0000000 0000000 00000010711 12633464636 0017544 0 ustar 00root root 0000000 0000000 import time,datetime,re, hashlib
from dateutil import tz
import os
from .constants import YowConstants
import codecs, sys
import logging
import tempfile
import base64
import hashlib
logger = logging.getLogger(__name__)
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():
#utc = tz.gettz('UTC')
utcNow = datetime.datetime.utcnow()
return TimeTools.datetimeToTimestamp(utcNow)
@staticmethod
def datetimeToTimestamp(dt):
return time.mktime(dt.timetuple())
class ModuleTools:
@staticmethod
def INSTALLED_PIL():
try:
import PIL
return True
except ImportError:
return False
@staticmethod
def INSTALLED_AXOLOTL():
try:
import axolotl
return True
except ImportError:
return False
class ImageTools:
@staticmethod
def scaleImage(infile, outfile, imageFormat, width, height):
if ModuleTools.INSTALLED_PIL():
from PIL import 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
else:
logger.warn("Python PIL library not installed")
return False
@staticmethod
def getImageDimensions(imageFile):
if ModuleTools.INSTALLED_PIL():
from PIL import Image
im = Image.open(imageFile)
return im.size
else:
logger.warn("Python PIL library not installed")
@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()
return preview
yowsup-2.4.48/yowsup/demos/ 0000775 0000000 0000000 00000000000 12633464636 0015651 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/__init__.py 0000664 0000000 0000000 00000000000 12633464636 0017750 0 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/cli/ 0000775 0000000 0000000 00000000000 12633464636 0016420 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/cli/__init__.py 0000664 0000000 0000000 00000000042 12633464636 0020525 0 ustar 00root root 0000000 0000000 from .stack import YowsupCliStack
yowsup-2.4.48/yowsup/demos/cli/cli.py 0000664 0000000 0000000 00000013607 12633464636 0017550 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.4.48/yowsup/demos/cli/layer.py 0000664 0000000 0000000 00000061700 12633464636 0020112 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
from yowsup.layers.network import YowNetworkLayer
import sys
from yowsup.common import YowConstants
import datetime
import os
import logging
from yowsup.layers.protocol_receipts.protocolentities import *
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_acks.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 ModuleTools
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}"
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 self.normalizeJid(ajid)
return self.normalizeJid(calias)
def jidToAlias(self, jid):
for alias, ajid in self.jidAliases.items():
if ajid == jid:
return alias
return jid
def normalizeJid(self, number):
if '@' in number:
return number
elif "-" in number:
return "%s@g.us" % number
return "%s@s.whatsapp.net" % number
def setCredentials(self, username, password):
self.getLayerInterface(YowAuthenticationProtocolLayer).setCredentials(username, password)
def onEvent(self, layerEvent):
if layerEvent.getName() == self.__class__.EVENT_START:
self.startInput()
return True
elif layerEvent.getName() == self.__class__.EVENT_SENDANDEXIT:
credentials = layerEvent.getArg("credentials")
target = layerEvent.getArg("target")
message = layerEvent.getArg("message")
self.sendMessageAndDisconnect(credentials, target, message)
return True
elif layerEvent.getName() == YowNetworkLayer.EVENT_STATE_DISCONNECTED:
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() and ModuleTools.INSTALLED_PIL():
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
from PIL import Image
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)
else:
logger.error("Python PIL library is not installed, can't set profile picture")
@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() and ModuleTools.INSTALLED_PIL():
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
from PIL import Image
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)
else:
logger.error("Python PIL library is not installed, can't set profile picture")
@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):
if ModuleTools.INSTALLED_AXOLOTL():
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)
else:
logger.error("Axolotl is not installed")
@clicmd("Send prekeys")
def keys_set(self):
if ModuleTools.INSTALLED_AXOLOTL():
from yowsup.layers.axolotl import YowAxolotlLayer
if self.assertConnected():
self.broadcastEvent(YowLayerEvent(YowAxolotlLayer.EVENT_PREKEYS_SET))
else:
logger.error("Axolotl is not installed")
@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 an image with optional caption")
def image_send(self, number, path, caption = None):
if self.assertConnected():
jid = self.aliasToJid(number)
entity = RequestUploadIqProtocolEntity(RequestUploadIqProtocolEntity.MEDIA_TYPE_IMAGE, filePath=path)
successFn = lambda successEntity, originalEntity: self.onRequestUploadResult(jid, path, successEntity, originalEntity, caption)
errorFn = lambda errorEntity, originalEntity: self.onRequestUploadError(jid, path, errorEntity, originalEntity)
self._sendIq(entity, successFn, errorFn)
@clicmd("Send audio file")
def audio_send(self, number, path):
if self.assertConnected():
jid = self.aliasToJid(number)
entity = RequestUploadIqProtocolEntity(RequestUploadIqProtocolEntity.MEDIA_TYPE_AUDIO, filePath=path)
successFn = lambda successEntity, originalEntity: self.onRequestUploadResult(jid, path, successEntity, originalEntity)
errorFn = lambda errorEntity, originalEntity: self.onRequestUploadError(jid, path, errorEntity, originalEntity)
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 doSendImage(self, filePath, url, to, ip = None, caption = None):
entity = ImageDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to, caption = caption)
self.toLower(entity)
def doSendAudio(self, filePath, url, to, ip = None, caption = None):
entity = AudioDownloadableMediaMessageProtocolEntity.fromFilePath(filePath, url, ip, to)
self.toLower(entity)
def __str__(self):
return "CLI Interface Layer"
########### callbacks ############
def onRequestUploadResult(self, jid, filePath, resultRequestUploadIqProtocolEntity, requestUploadIqProtocolEntity, caption = None):
if requestUploadIqProtocolEntity.mediaType == RequestUploadIqProtocolEntity.MEDIA_TYPE_AUDIO:
doSendFn = self.doSendAudio
else:
doSendFn = self.doSendImage
if resultRequestUploadIqProtocolEntity.isDuplicate():
doSendFn(filePath, resultRequestUploadIqProtocolEntity.getUrl(), jid,
resultRequestUploadIqProtocolEntity.getIp(), caption)
else:
successFn = lambda filePath, jid, url: doSendFn(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.4.48/yowsup/demos/cli/stack.py 0000664 0000000 0000000 00000002016 12633464636 0020076 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.auth import YowAuthenticationProtocolLayer
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)
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.4.48/yowsup/demos/contacts/ 0000775 0000000 0000000 00000000000 12633464636 0017467 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/contacts/__init__.py 0000664 0000000 0000000 00000000043 12633464636 0021575 0 ustar 00root root 0000000 0000000 from .stack import YowsupSyncStack
yowsup-2.4.48/yowsup/demos/contacts/layer.py 0000664 0000000 0000000 00000002316 12633464636 0021157 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.4.48/yowsup/demos/contacts/stack.py 0000664 0000000 0000000 00000004551 12633464636 0021153 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStack
from .layer import SyncLayer
from yowsup.layers import YowLayerEvent
from yowsup.layers.auth import YowCryptLayer, YowAuthenticationProtocolLayer, AuthError
from yowsup.layers.coder import YowCoderLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.stanzaregulator import YowStanzaRegulator
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.logger import YowLoggerLayer
from yowsup.layers.protocol_contacts import YowContactsIqProtocolLayer
from yowsup.layers import YowParallelLayer
class YowsupSyncStack(object):
def __init__(self, credentials, contacts, encryptionEnabled = False):
"""
:param credentials:
:param contacts: list of [jid ]
:param encryptionEnabled:
:return:
"""
if encryptionEnabled:
from yowsup.layers.axolotl import YowAxolotlLayer
layers = (
SyncLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowContactsIqProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer]),
YowAxolotlLayer,
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
else:
layers = (
SyncLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowContactsIqProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer]),
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
self.stack = YowStack(layers)
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.4.48/yowsup/demos/echoclient/ 0000775 0000000 0000000 00000000000 12633464636 0017766 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/echoclient/__init__.py 0000664 0000000 0000000 00000000042 12633464636 0022073 0 ustar 00root root 0000000 0000000 from .stack import YowsupEchoStack yowsup-2.4.48/yowsup/demos/echoclient/layer.py 0000664 0000000 0000000 00000003156 12633464636 0021461 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.4.48/yowsup/demos/echoclient/stack.py 0000664 0000000 0000000 00000004643 12633464636 0021454 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStack
from .layer import EchoLayer
from yowsup.layers import YowLayerEvent
from yowsup.layers.auth import YowCryptLayer, YowAuthenticationProtocolLayer, AuthError
from yowsup.layers.coder import YowCoderLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer
from yowsup.layers.protocol_media import YowMediaProtocolLayer
from yowsup.layers.stanzaregulator import YowStanzaRegulator
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.logger import YowLoggerLayer
from yowsup.layers.protocol_iq import YowIqProtocolLayer
from yowsup.layers.protocol_calls import YowCallsProtocolLayer
from yowsup.layers import YowParallelLayer
class YowsupEchoStack(object):
def __init__(self, credentials, encryptionEnabled = False):
if encryptionEnabled:
from yowsup.layers.axolotl import YowAxolotlLayer
layers = (
EchoLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer, YowMediaProtocolLayer, YowIqProtocolLayer, YowCallsProtocolLayer]),
YowAxolotlLayer,
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
else:
layers = (
EchoLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer, YowMediaProtocolLayer, YowIqProtocolLayer, YowCallsProtocolLayer]),
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
self.stack = YowStack(layers)
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.4.48/yowsup/demos/sendclient/ 0000775 0000000 0000000 00000000000 12633464636 0020001 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/demos/sendclient/__init__.py 0000664 0000000 0000000 00000000042 12633464636 0022106 0 ustar 00root root 0000000 0000000 from .stack import YowsupSendStack yowsup-2.4.48/yowsup/demos/sendclient/layer.py 0000664 0000000 0000000 00000004300 12633464636 0021464 0 ustar 00root root 0000000 0000000 from yowsup.layers.interface import YowInterfaceLayer, ProtocolEntityCallback
from yowsup.layers.protocol_messages.protocolentities import TextMessageProtocolEntity
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
if '@' in phone:
messageEntity = TextMessageProtocolEntity(message, to = phone)
elif '-' in phone:
messageEntity = TextMessageProtocolEntity(message, to = "%s@g.us" % phone)
else:
messageEntity = TextMessageProtocolEntity(message, to = "%s@s.whatsapp.net" % 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.4.48/yowsup/demos/sendclient/stack.py 0000664 0000000 0000000 00000004563 12633464636 0021470 0 ustar 00root root 0000000 0000000 from yowsup.stacks import YowStack
from .layer import SendLayer
from yowsup.layers import YowLayerEvent
from yowsup.layers.auth import YowCryptLayer, YowAuthenticationProtocolLayer, AuthError
from yowsup.layers.coder import YowCoderLayer
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.protocol_messages import YowMessagesProtocolLayer
from yowsup.layers.stanzaregulator import YowStanzaRegulator
from yowsup.layers.protocol_receipts import YowReceiptProtocolLayer
from yowsup.layers.protocol_acks import YowAckProtocolLayer
from yowsup.layers.logger import YowLoggerLayer
from yowsup.layers import YowParallelLayer
class YowsupSendStack(object):
def __init__(self, credentials, messages, encryptionEnabled = False):
"""
:param credentials:
:param messages: list of (jid, message) tuples
:param encryptionEnabled:
:return:
"""
if encryptionEnabled:
from yowsup.layers.axolotl import YowAxolotlLayer
layers = (
SendLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer]),
YowAxolotlLayer,
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
else:
layers = (
SendLayer,
YowParallelLayer([YowAuthenticationProtocolLayer, YowMessagesProtocolLayer, YowReceiptProtocolLayer, YowAckProtocolLayer]),
YowLoggerLayer,
YowCoderLayer,
YowCryptLayer,
YowStanzaRegulator,
YowNetworkLayer
)
self.stack = YowStack(layers)
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.4.48/yowsup/env/ 0000775 0000000 0000000 00000000000 12633464636 0015332 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/env/__init__.py 0000664 0000000 0000000 00000000152 12633464636 0017441 0 ustar 00root root 0000000 0000000 from .env_android import AndroidYowsupEnv
from .env_s40 import S40YowsupEnv
CURRENT_ENV = S40YowsupEnv()
yowsup-2.4.48/yowsup/env/env.py 0000664 0000000 0000000 00000001651 12633464636 0016477 0 ustar 00root root 0000000 0000000 import abc
class YowsupEnv(object):
__metaclass__ = abc.ABCMeta
_USERAGENT_STRING = "WhatsApp/{WHATSAPP_VERSION} {OS_NAME}/{OS_VERSION} Device/{DEVICE_NAME}"
@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 isAxolotlEnabled(self):
pass
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(),
DEVICE_NAME = self.getDeviceName()
)
yowsup-2.4.48/yowsup/env/env_android.py 0000664 0000000 0000000 00000005427 12633464636 0020204 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 = "vIDGGxIcIxeBP0GoG8yL8g=="
_KEY = "/UIGKU1FVQa+ATM2A0za7G2KI9S/CwPYjgAbc67v7ep42eO/WeTLx1lb1cHwxpsEgF4+PmYpLd2YpGUdX/A2JQitsHzDwgcdBpUf7psX1BU="
_VERSION = "2.12.357"
_OS_NAME = "Android"
_OS_VERSION = "4.3"
_DEVICE_NAME = "GalaxyS3"
_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 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.4.48/yowsup/env/env_s40.py 0000664 0000000 0000000 00000002061 12633464636 0017161 0 ustar 00root root 0000000 0000000 from .env import YowsupEnv
import base64
import hashlib
class S40YowsupEnv(YowsupEnv):
_VERSION = "2.13.21"
_OS_NAME= "S40"
_OS_VERSION = "14.26"
_DEVICE_NAME = "Nokia302"
_TOKEN_STRING = "PdA2DJyKoUrwLw1Bg6EIhzh502dF9noR9uFCllGk1447796090073{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 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()
)
yowsup-2.4.48/yowsup/env/test_env_s40.py 0000664 0000000 0000000 00000000600 12633464636 0020215 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.4.48/yowsup/layers/ 0000775 0000000 0000000 00000000000 12633464636 0016041 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/__init__.py 0000664 0000000 0000000 00000015442 12633464636 0020160 0 ustar 00root root 0000000 0000000 import unittest
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 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
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):
if self.__lower:
self.__lower.send(data)
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):
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
def receiveOverrider(self, data):
self.upperSink.append(data)
def sendOverrider(self, data):
self.lowerSink.append(data)
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.4.48/yowsup/layers/auth/ 0000775 0000000 0000000 00000000000 12633464636 0017002 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/auth/__init__.py 0000664 0000000 0000000 00000000242 12633464636 0021111 0 ustar 00root root 0000000 0000000 from .layer_crypt import YowCryptLayer
from .layer_authentication import YowAuthenticationProtocolLayer
from .autherror import AuthError
#import protocolentities
yowsup-2.4.48/yowsup/layers/auth/autherror.py 0000664 0000000 0000000 00000000044 12633464636 0021365 0 ustar 00root root 0000000 0000000 class AuthError(Exception):
pass yowsup-2.4.48/yowsup/layers/auth/keystream.py 0000664 0000000 0000000 00000007570 12633464636 0021371 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.4.48/yowsup/layers/auth/layer_authentication.py 0000664 0000000 0000000 00000013652 12633464636 0023576 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayerEvent, YowProtocolLayer
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 .layer_interface_authentication import YowAuthenticationProtocolLayerInterface
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.whatsapp.net" % self._credentials[0])
else:
prop = self.getProp(YowAuthenticationProtocolLayer.PROP_CREDENTIALS)
return prop[0] if prop else None
def onEvent(self, event):
if event.getName() == YowNetworkLayer.EVENT_STATE_CONNECTED:
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):
if node.getChild("text"):
nodeEntity = StreamErrorConflictProtocolEntity.fromProtocolTreeNode(node)
elif node.getChild("ack"):
nodeEntity = StreamErrorAckProtocolEntity.fromProtocolTreeNode(node)
else:
raise AuthError("Unhandled stream:error node:\n%s" % node)
self.toUpper(nodeEntity)
##senders
def _sendFeatures(self):
self.entityToLower(StreamFeaturesProtocolEntity(["readreceipts", "groups_v2", "privacy", "presence"]))
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)
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)
encoded = outputKey.encodeMessage(nums, 0, 4, len(nums) - 4)
authBlob = "".join(map(chr, encoded))
return (inputKey, outputKey, authBlob)
yowsup-2.4.48/yowsup/layers/auth/layer_crypt.py 0000664 0000000 0000000 00000004073 12633464636 0021715 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer
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)
def onEvent(self, yowLayerEvent):
if yowLayerEvent.getName() == YowNetworkLayer.EVENT_STATE_CONNECTED:
self.keys = (None,None)
elif yowLayerEvent.getName() == YowCryptLayer.EVENT_KEYS_READY:
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.4.48/yowsup/layers/auth/layer_interface_authentication.py 0000664 0000000 0000000 00000000453 12633464636 0025611 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.4.48/yowsup/layers/auth/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0022410 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/auth/protocolentities/__init__.py 0000664 0000000 0000000 00000000621 12633464636 0024520 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_conflict import StreamErrorConflictProtocolEntity
from .stream_error_ack import StreamErrorAckProtocolEntity
yowsup-2.4.48/yowsup/layers/auth/protocolentities/auth.py 0000664 0000000 0000000 00000001674 12633464636 0023733 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.4.48/yowsup/layers/auth/protocolentities/challenge.py 0000664 0000000 0000000 00000001443 12633464636 0024706 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.4.48/yowsup/layers/auth/protocolentities/failure.py 0000664 0000000 0000000 00000001254 12633464636 0024413 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.4.48/yowsup/layers/auth/protocolentities/response.py 0000664 0000000 0000000 00000001103 12633464636 0024613 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.4.48/yowsup/layers/auth/protocolentities/stream_error_ack.py 0000664 0000000 0000000 00000001207 12633464636 0026304 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class StreamErrorAckProtocolEntity(ProtocolEntity):
'''
'''
def __init__(self):
super(StreamErrorAckProtocolEntity, self).__init__("stream:error")
def toProtocolTreeNode(self):
node = super(StreamErrorAckProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("ack"))
return node
def __str__(self):
out = "Ack Stream Error\n"
return out
@staticmethod
def fromProtocolTreeNode(node):
return StreamErrorAckProtocolEntity()
yowsup-2.4.48/yowsup/layers/auth/protocolentities/stream_error_conflict.py 0000664 0000000 0000000 00000002046 12633464636 0027351 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
class StreamErrorConflictProtocolEntity(ProtocolEntity):
'''
Replaced by new connection
'''
def __init__(self, text = None):
super(StreamErrorConflictProtocolEntity, self).__init__("stream:error")
self.setText(text)
def setText(self, text = None):
self.text = text or ''
def getText(self):
return self.text
def __str__(self):
out = "Conflict Stream Error\n"
if self.text:
out += "Text: %s\n" % self.getText()
return out
def toProtocolTreeNode(self):
node = super(StreamErrorConflictProtocolEntity, self).toProtocolTreeNode()
node.addChild(ProtocolTreeNode("conflict"))
node.addChild(ProtocolTreeNode("text", data=self.text))
return node
@staticmethod
def fromProtocolTreeNode(node):
return StreamErrorConflictProtocolEntity(node.getChild("text").getData())
yowsup-2.4.48/yowsup/layers/auth/protocolentities/stream_features.py 0000664 0000000 0000000 00000001273 12633464636 0026156 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.4.48/yowsup/layers/auth/protocolentities/success.py 0000664 0000000 0000000 00000003173 12633464636 0024436 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.4.48/yowsup/layers/auth/protocolentities/test_auth.py 0000664 0000000 0000000 00000000667 12633464636 0024773 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.4.48/yowsup/layers/auth/protocolentities/test_challenge.py 0000664 0000000 0000000 00000001021 12633464636 0025735 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.4.48/yowsup/layers/auth/protocolentities/test_failure.py 0000664 0000000 0000000 00000000666 12633464636 0025460 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.4.48/yowsup/layers/auth/protocolentities/test_response.py 0000664 0000000 0000000 00000000777 12633464636 0025672 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.4.48/yowsup/layers/auth/protocolentities/test_stream_features.py 0000664 0000000 0000000 00000001046 12633464636 0027213 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.4.48/yowsup/layers/auth/protocolentities/test_success.py 0000664 0000000 0000000 00000001176 12633464636 0025476 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.4.48/yowsup/layers/auth/test_authenticator.py 0000664 0000000 0000000 00000002737 12633464636 0023276 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(["readreceipts","groups_v2","privacy","presence"]).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.4.48/yowsup/layers/auth/test_crypt.py 0000664 0000000 0000000 00000002513 12633464636 0021555 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.4.48/yowsup/layers/auth/test_keystream.py 0000664 0000000 0000000 00000004405 12633464636 0022422 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.4.48/yowsup/layers/axolotl/ 0000775 0000000 0000000 00000000000 12633464636 0017523 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/axolotl/__init__.py 0000664 0000000 0000000 00000000042 12633464636 0021630 0 ustar 00root root 0000000 0000000 from .layer import YowAxolotlLayer yowsup-2.4.48/yowsup/layers/axolotl/layer.py 0000664 0000000 0000000 00000040031 12633464636 0021207 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowProtocolLayer, YowLayerEvent
from .protocolentities import SetKeysIqProtocolEntity
from axolotl.util.keyhelper import KeyHelper
from .store.sqlite.liteaxolotlstore import LiteAxolotlStore
from axolotl.sessionbuilder import SessionBuilder
from yowsup.layers.protocol_messages.protocolentities.message import MessageProtocolEntity
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.network.layer import YowNetworkLayer
from yowsup.layers.auth.layer_authentication import YowAuthenticationProtocolLayer
from axolotl.ecc.curve import Curve
from yowsup.common.tools import StorageTools
from axolotl.protocol.prekeywhispermessage import PreKeyWhisperMessage
from axolotl.protocol.whispermessage import WhisperMessage
from .protocolentities import EncryptedMessageProtocolEntity
from axolotl.sessioncipher import SessionCipher
from yowsup.structs import ProtocolTreeNode
from .protocolentities import GetKeysIqProtocolEntity, ResultGetKeysIqProtocolEntity
from axolotl.util.hexutil import HexUtil
from axolotl.invalidmessageexception import InvalidMessageException
from axolotl.duplicatemessagexception import DuplicateMessageException
from .protocolentities import EncryptNotification
from yowsup.layers.protocol_acks.protocolentities import OutgoingAckProtocolEntity
from axolotl.invalidkeyidexception import InvalidKeyIdException
from axolotl.nosessionexception import NoSessionException
from axolotl.untrustedidentityexception import UntrustedIdentityException
from .protocolentities.receipt_outgoing_retry import RetryOutgoingReceiptProtocolEntity
import binascii
import sys
import logging
logger = logging.getLogger(__name__)
class YowAxolotlLayer(YowProtocolLayer):
EVENT_PREKEYS_SET = "org.openwhatsapp.yowsup.events.axololt.setkeys"
_STATE_INIT = 0
_STATE_GENKEYS = 1
_STATE_HASKEYS = 2
_COUNT_PREKEYS = 200
_DB = "axolotl.db"
def __init__(self):
super(YowAxolotlLayer, self).__init__()
self.store = None
self.state = self.__class__._STATE_INIT
self.sessionCiphers = {}
self.pendingMessages = {}
self.pendingIncomingMessages = {}
self.skipEncJids = []
self.v2Jids = [] #people we're going to send v2 enc messages
@property
def store(self):
if self._store is None:
self.store = LiteAxolotlStore(
StorageTools.constructPath(
self.getProp(
YowAuthenticationProtocolLayer.PROP_CREDENTIALS)[0],
self.__class__._DB
)
)
self.state = self.__class__._STATE_HASKEYS if self.store.getLocalRegistrationId() is not None \
else self.__class__._STATE_INIT
return self._store
@store.setter
def store(self, store):
self._store = store
def __str__(self):
return "Axolotl Layer"
### store and state
def isInitState(self):
return self.store == None or self.state == self.__class__._STATE_INIT
def isGenKeysState(self):
return self.state == self.__class__._STATE_GENKEYS
########
### standard layer methods ###
def onEvent(self, yowLayerEvent):
if yowLayerEvent.getName() == self.__class__.EVENT_PREKEYS_SET:
self.sendKeys(fresh=False)
elif yowLayerEvent.getName() == YowNetworkLayer.EVENT_STATE_CONNECTED:
if self.isInitState():
self.setProp(YowAuthenticationProtocolLayer.PROP_PASSIVE, True)
elif yowLayerEvent.getName() == YowAuthenticationProtocolLayer.EVENT_AUTHED:
if yowLayerEvent.getArg("passive") and self.isInitState():
logger.info("Axolotl layer is generating keys")
self.sendKeys()
elif yowLayerEvent.getName() == YowNetworkLayer.EVENT_STATE_DISCONNECTED:
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
def send(self, node):
if node.tag == "message" and node["type"] == "text" and node["to"] not in self.skipEncJids:
self.handlePlaintextNode(node)
return
self.toLower(node)
def receive(self, protocolTreeNode):
"""
:type protocolTreeNode: ProtocolTreeNode
"""
if not self.processIqRegistry(protocolTreeNode):
if protocolTreeNode.tag == "message":
self.onMessage(protocolTreeNode)
return
elif protocolTreeNode.tag == "notification" and protocolTreeNode["type"] == "encrypt":
self.onEncryptNotification(protocolTreeNode)
return
elif protocolTreeNode.tag == "receipt" and protocolTreeNode["type"] == "retry":
# should bring up that message, resend it, but in upper layer?
# as it might have to be fetched from a persistent storage
pass
self.toUpper(protocolTreeNode)
######
##### handling received data #####
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())
def onMessage(self, protocolTreeNode):
encNode = protocolTreeNode.getChild("enc")
if encNode:
self.handleEncMessage(protocolTreeNode)
else:
self.toUpper(protocolTreeNode)
####
def processPendingMessages(self, jid):
if jid in self.pendingMessages:
for messageNode in self.pendingMessages[jid]:
if jid in self.skipEncJids:
self.toLower(messageNode)
else:
self.handlePlaintextNode(messageNode)
del self.pendingMessages[jid]
def processPendingIncomingMessages(self, jid):
if jid in self.pendingIncomingMessages:
for messageNode in self.pendingIncomingMessages[jid]:
self.onMessage(messageNode)
del self.pendingIncomingMessages[jid]
#### handling message types
def handlePlaintextNode(self, node):
plaintext = node.getChild("body").getData()
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
recipient_id = entity.getTo(False)
if not self.store.containsSession(recipient_id, 1):
entity = GetKeysIqProtocolEntity([node["to"]])
if node["to"] not in self.pendingMessages:
self.pendingMessages[node["to"]] = []
self.pendingMessages[node["to"]].append(node)
self._sendIq(entity, lambda a, b: self.onGetKeysResult(a, b, self.processPendingMessages), self.onGetKeysError)
else:
sessionCipher = self.getSessionCipher(recipient_id)
if node["to"] in self.v2Jids:
version = 2
padded = bytearray()
padded.append(ord("\n"))
padded.extend(self.encodeInt7bit(len(plaintext)))
padded.extend(plaintext)
padded.append(ord("\x01"))
plaintext = padded
else:
version = 1
ciphertext = sessionCipher.encrypt(plaintext)
encEntity = EncryptedMessageProtocolEntity(
EncryptedMessageProtocolEntity.TYPE_MSG if ciphertext.__class__ == WhisperMessage else EncryptedMessageProtocolEntity.TYPE_PKMSG ,
version,
ciphertext.serialize(),
MessageProtocolEntity.MESSAGE_TYPE_TEXT,
_id= node["id"],
to = node["to"],
notify = node["notify"],
timestamp= node["timestamp"],
participant=node["participant"],
offline=node["offline"],
retry=node["retry"]
)
self.toLower(encEntity.toProtocolTreeNode())
def encodeInt7bit(self, value):
v = value
out = bytearray()
while v >= 0x80:
out.append((v | 0x80) % 256)
v >>= 7
out.append(v % 256)
return out
def handleEncMessage(self, node):
try:
if node.getChild("enc")["v"] == "2" and node["from"] not in self.v2Jids:
self.v2Jids.append(node["from"])
if node.getChild("enc")["type"] == "pkmsg":
self.handlePreKeyWhisperMessage(node)
else:
self.handleWhisperMessage(node)
except InvalidMessageException as e:
# logger.error("Invalid message from %s!! Your axololtl database data might be inconsistent with WhatsApp, or with what that contact has" % node["from"])
# sys.exit(1)
logger.error(e)
retry = RetryOutgoingReceiptProtocolEntity.fromMesageNode(node)
retry.setRegData(self.store.getLocalRegistrationId())
self.toLower(retry.toProtocolTreeNode())
except InvalidKeyIdException as e:
logger.error(e)
retry = RetryOutgoingReceiptProtocolEntity.fromMesageNode(node)
retry.setRegData(self.store.getLocalRegistrationId())
self.toLower(retry.toProtocolTreeNode())
except NoSessionException as e:
logger.error(e)
entity = GetKeysIqProtocolEntity([node["from"]])
if node["from"] not in self.pendingIncomingMessages:
self.pendingIncomingMessages[node["from"]] = []
self.pendingIncomingMessages[node["from"]].append(node)
self._sendIq(entity, lambda a, b: self.onGetKeysResult(a, b, self.processPendingIncomingMessages), self.onGetKeysError)
except DuplicateMessageException as e:
logger.error(e)
logger.warning("Going to send the delivery receipt myself !")
self.toLower(OutgoingReceiptProtocolEntity(node["id"], node["from"]).toProtocolTreeNode())
except UntrustedIdentityException as e:
logger.error(e)
logger.warning("Ignoring message with untrusted identity")
def handlePreKeyWhisperMessage(self, node):
pkMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
preKeyWhisperMessage = PreKeyWhisperMessage(serialized=pkMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(pkMessageProtocolEntity.getFrom(False))
plaintext = sessionCipher.decryptPkmsg(preKeyWhisperMessage)
if pkMessageProtocolEntity.getVersion() == 2:
plaintext = self.unpadV2Plaintext(plaintext)
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
def handleWhisperMessage(self, node):
encMessageProtocolEntity = EncryptedMessageProtocolEntity.fromProtocolTreeNode(node)
whisperMessage = WhisperMessage(serialized=encMessageProtocolEntity.getEncData())
sessionCipher = self.getSessionCipher(encMessageProtocolEntity.getFrom(False))
plaintext = sessionCipher.decryptMsg(whisperMessage)
if encMessageProtocolEntity.getVersion() == 2:
plaintext = self.unpadV2Plaintext(plaintext)
bodyNode = ProtocolTreeNode("body", data = plaintext)
node.addChild(bodyNode)
self.toUpper(node)
def unpadV2Plaintext(self, v2plaintext):
if len(v2plaintext) < 128:
return v2plaintext[2:-1]
else: # < 128 * 128
return v2plaintext[3: -1]
####
### 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 onGetKeysResult(self, resultNode, getKeysEntity, processPendingFn):
entity = ResultGetKeysIqProtocolEntity.fromProtocolTreeNode(resultNode)
resultJids = entity.getJids()
for jid in getKeysEntity.getJids():
if jid not in resultJids:
self.skipEncJids.append(jid)
self.processPendingMessages(jid)
continue
recipient_id = jid.split('@')[0]
preKeyBundle = entity.getPreKeyBundleFor(jid)
sessionBuilder = SessionBuilder(self.store, self.store, self.store,
self.store, recipient_id, 1)
sessionBuilder.processPreKeyBundle(preKeyBundle)
processPendingFn(jid)
def onGetKeysError(self, errorNode, getKeysEntity):
pass
###
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)
def getSessionCipher(self, recipientId):
if recipientId in self.sessionCiphers:
return self.sessionCiphers[recipientId]
else:
self.sessionCiphers[recipientId] = SessionCipher(self.store, self.store, self.store, self.store, recipientId, 1)
return self.sessionCiphers[recipientId]
yowsup-2.4.48/yowsup/layers/axolotl/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0023131 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/axolotl/protocolentities/__init__.py 0000664 0000000 0000000 00000000422 12633464636 0025240 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 .notification_encrypt import EncryptNotification yowsup-2.4.48/yowsup/layers/axolotl/protocolentities/iq_key_get.py 0000664 0000000 0000000 00000001520 12633464636 0025621 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/axolotl/protocolentities/iq_keys_get_result.py 0000664 0000000 0000000 00000013014 12633464636 0027403 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net", _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.4.48/yowsup/layers/axolotl/protocolentities/iq_keys_set.py 0000664 0000000 0000000 00000005420 12633464636 0026023 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/axolotl/protocolentities/message_encrypted.py 0000664 0000000 0000000 00000004554 12633464636 0027214 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_messages.protocolentities import MessageProtocolEntity
from yowsup.structs import ProtocolTreeNode
import sys
class EncryptedMessageProtocolEntity(MessageProtocolEntity):
'''
HEX:33089eb3c90312210510e0196be72fe65913c6a84e75a54f40a3ee290574d6a23f408df990e718da761a210521f1a3f3d5cb87fde19fadf618d3001b64941715efd3e0f36bba48c23b08c82f2242330a21059b0ce2c4720ec79719ba862ee3cda6d6332746d05689af13aabf43ea1c8d747f100018002210d31cd6ebea79e441c4935f72398c772e2ee21447eb675cfa28b99de8d2013000
'''
TYPE_PKMSG = "pkmsg"
TYPE_MSG = "msg"
def __init__(self, encType, encVersion, encData, _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.setEncProps(encType, encVersion, encData)
def setEncProps(self, encType, encVersion, encData):
assert encType in "pkmsg", "msg"
self.encType = encType
self.encVersion = int(encVersion)
self.encData = encData
def getEncType(self):
return self.encType
def getEncData(self):
return self.encData
def getVersion(self):
return self.encVersion
def toProtocolTreeNode(self):
node = super(EncryptedMessageProtocolEntity, self).toProtocolTreeNode()
encNode = ProtocolTreeNode("enc", data = self.encData)
encNode["type"] = self.encType
encNode["v"] = str(self.encVersion)
node.addChild(encNode)
return node
@staticmethod
def fromProtocolTreeNode(node):
entity = MessageProtocolEntity.fromProtocolTreeNode(node)
entity.__class__ = EncryptedMessageProtocolEntity
encNode = node.getChild("enc")
entity.setEncProps(encNode["type"], encNode["v"],
encNode.data.encode('latin-1') if sys.version_info >= (3,0) else encNode.data)
return entity yowsup-2.4.48/yowsup/layers/axolotl/protocolentities/notification_encrypt.py 0000664 0000000 0000000 00000002235 12633464636 0027737 0 ustar 00root root 0000000 0000000 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, "s.whatsapp.net", 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.4.48/yowsup/layers/axolotl/protocolentities/receipt_outgoing_retry.py 0000664 0000000 0000000 00000004631 12633464636 0030302 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, 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, to, t, v = "1", count = "1",regData = ""):
super(RetryOutgoingReceiptProtocolEntity, self).__init__(_id,to)
self.setRetryData(t,v,count,regData)
def setRetryData(self, t,v,count,regData):
self.t = int(t)
self.v = int(v)
self.count = int(count)
self.regData = regData
def setRegData(self,regData):
'''
In axolotl layer:
regData = self.store.getLocalRegistrationId()
'''
self.regData = ResultGetKeysIqProtocolEntity._intToBytes(regData)
def toProtocolTreeNode(self):
node = super(RetryOutgoingReceiptProtocolEntity, self).toProtocolTreeNode()
node.setAttribute("type", "retry")
retry = ProtocolTreeNode("retry", {"count": str(self.count),"t":str(self.t),"id":self.getId(),"v":str(self.v)})
node.addChild(retry)
registration = ProtocolTreeNode("registration",data=self.regData)
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(retryNode["t"], retryNode["v"], retryNode["count"], node.getChild("registration").data)
@staticmethod
def fromMesageNode(MessageNodeToBeRetried):
return RetryOutgoingReceiptProtocolEntity(
MessageNodeToBeRetried.getAttributeValue("id"),
MessageNodeToBeRetried.getAttributeValue("from"),
MessageNodeToBeRetried.getAttributeValue("t"),
MessageNodeToBeRetried.getChild("enc").getAttributeValue("v")
) yowsup-2.4.48/yowsup/layers/axolotl/protocolentities/test_iq_keys_get_result.py 0000664 0000000 0000000 00000005351 12633464636 0030447 0 ustar 00root root 0000000 0000000 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.whatsapp.net" % i})
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.4.48/yowsup/layers/axolotl/protocolentities/test_iq_keys_set.py 0000664 0000000 0000000 00000001747 12633464636 0027072 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.4.48/yowsup/layers/axolotl/protocolentities/test_notification_encrypt.py 0000664 0000000 0000000 00000000746 12633464636 0031003 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.4.48/yowsup/layers/axolotl/store/ 0000775 0000000 0000000 00000000000 12633464636 0020657 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/axolotl/store/__init__.py 0000664 0000000 0000000 00000000000 12633464636 0022756 0 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/axolotl/store/sqlite/ 0000775 0000000 0000000 00000000000 12633464636 0022160 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/axolotl/store/sqlite/__init__.py 0000664 0000000 0000000 00000000025 12633464636 0024266 0 ustar 00root root 0000000 0000000 __author__ = 'tarek'
yowsup-2.4.48/yowsup/layers/axolotl/store/sqlite/liteaxolotlstore.py 0000664 0000000 0000000 00000005764 12633464636 0026163 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
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)
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) yowsup-2.4.48/yowsup/layers/axolotl/store/sqlite/liteidentitykeystore.py 0000664 0000000 0000000 00000005377 12633464636 0027043 0 ustar 00root root 0000000 0000000 from axolotl.state.identitykeystore import IdentityKeyStore
from axolotl.ecc.curve import Curve
from axolotl.identitykey import IdentityKey
from axolotl.util.keyhelper import KeyHelper
from axolotl.identitykeypair import IdentityKeyPair
from axolotl.ecc.djbec import *
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()
c.execute(q, (registrationId, identityKeyPair.getPublicKey().getPublicKey().serialize(),
identityKeyPair.getPrivateKey().serialize()))
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()
c.execute(q, (recipientId, identityKey.getPublicKey().serialize()))
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
return result[0] == identityKey.getPublicKey().serialize() yowsup-2.4.48/yowsup/layers/axolotl/store/sqlite/liteprekeystore.py 0000664 0000000 0000000 00000003321 12633464636 0025763 0 ustar 00root root 0000000 0000000 from axolotl.state.prekeystore import PreKeyStore
from axolotl.state.prekeyrecord import PreKeyRecord
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()
cursor.execute(q, (preKeyId, preKeyRecord.serialize()))
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.4.48/yowsup/layers/axolotl/store/sqlite/litesessionstore.py 0000664 0000000 0000000 00000004153 12633464636 0026153 0 ustar 00root root 0000000 0000000 from axolotl.state.sessionstore import SessionStore
from axolotl.state.sessionrecord import SessionRecord
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()
c.execute(q, (recipientId, deviceId, sessionRecord.serialize()))
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.4.48/yowsup/layers/axolotl/store/sqlite/litesignedprekeystore.py 0000664 0000000 0000000 00000004217 12633464636 0027162 0 ustar 00root root 0000000 0000000 from axolotl.state.signedprekeystore import SignedPreKeyStore
from axolotl.state.signedprekeyrecord import SignedPreKeyRecord
from axolotl.invalidkeyidexception import InvalidKeyIdException
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()
cursor.execute(q, (signedPreKeyId, signedPreKeyRecord.serialize()))
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.4.48/yowsup/layers/coder/ 0000775 0000000 0000000 00000000000 12633464636 0017135 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/coder/__init__.py 0000664 0000000 0000000 00000000040 12633464636 0021240 0 ustar 00root root 0000000 0000000 from .layer import YowCoderLayer yowsup-2.4.48/yowsup/layers/coder/decoder.py 0000664 0000000 0000000 00000012351 12633464636 0021116 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolTreeNode
import math
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 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 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 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 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(data.pop(0), data)
value = self.readString(data.pop(0), data)
attribs[key]=value
return attribs
def readString(self,token, data):
if token == -1:
raise Exception("-1 token in readString")
if token > 2 and token < 245:
return self._getToken(token, data)
if token == 0:
return None
if token == 252:
size8 = self.readInt8(data)
buf8 = self.readArray(size8, data)
return "".join(map(chr, buf8))
if token == 253:
size24 = self.readInt24(data)
buf24 = self.readArray(size24, data)
return "".join(map(chr, buf24))
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")
elif token == 255:
return self.readNibble(data)
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):
b = data.pop(0)
size = self.readListSize(b, data)
b = data.pop(0)
if b == 2:
return None
tag = self.readString(b, 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)
b = data.pop(0)
if self.isListTag(b):
return ProtocolTreeNode(tag,attribs,self.readList(b, data))
return ProtocolTreeNode(tag, attribs, None, self.readString(b, data))
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.4.48/yowsup/layers/coder/encoder.py 0000664 0000000 0000000 00000007646 12633464636 0021143 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(5)
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);
def writeBytes(self, bytes, data):
length = len(bytes)
if length >= 256:
data.append(253)
self.writeInt24(length, data)
else:
data.append(252)
self.writeInt8(length, data)
for b in bytes:
if type(b) is int:
data.append(b)
else:
data.append(ord(b))
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 writeInt24(self, v, data):
data.append((v & 0xFF0000) >> 16)
data.append((v & 0xFF00) >> 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, intValue, data):
if intValue < 245:
data.append(intValue)
elif intValue <=500:
data.append(254)
data.append(intValue - 245)
def writeString(self, tag, data):
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)
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)
else:
self.writeToken(0, data)
self.writeString(server, data)
yowsup-2.4.48/yowsup/layers/coder/layer.py 0000664 0000000 0000000 00000002710 12633464636 0020623 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent
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)
def onEvent(self, event):
if event.getName() == YowNetworkLayer.EVENT_STATE_CONNECTED:
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.4.48/yowsup/layers/coder/test_decoder.py 0000664 0000000 0000000 00000001460 12633464636 0022154 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, 89, 165, 252, 3, 120, 121, 122, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 248, 1,
248, 4, 87, 236, 99, 252, 3, 49, 50, 51, 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.4.48/yowsup/layers/coder/test_encoder.py 0000664 0000000 0000000 00000001771 12633464636 0022173 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, 89, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 165, 252, 3, 120, 121, 122, 248, 1,
248, 4, 87, 236, 99, 252, 3, 49, 50, 51, 252, 6, 49, 50, 51, 52, 53, 54],
[248, 6, 89, 165, 252, 3, 120, 121, 122, 252, 4, 102, 111, 114, 109, 252, 3, 97, 98, 99, 248, 1,
248, 4, 87, 236, 99, 252, 3, 49, 50, 51, 252, 6, 49, 50, 51, 52, 53, 54])
)
yowsup-2.4.48/yowsup/layers/coder/test_tokendictionary.py 0000664 0000000 0000000 00000001337 12633464636 0023760 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(74), "iq")
def test_getIndex(self):
self.assertEqual(self.tokenDictionary.getIndex("iq"), (74, False))
def test_getSecondaryToken(self):
self.assertEqual(self.tokenDictionary.getToken(238), "wmv")
def test_getSecondaryTokenExplicit(self):
self.assertEqual(self.tokenDictionary.getToken(1, True), "wmv")
def test_getSecondaryIndex(self):
self.assertEqual(self.tokenDictionary.getIndex("wmv"), (1, True)) yowsup-2.4.48/yowsup/layers/coder/tokendictionary.py 0000664 0000000 0000000 00000026767 12633464636 0022737 0 ustar 00root root 0000000 0000000 class TokenDictionary:
def __init__(self):
self.dictionary = [
"",
"",
"",
"account",
"ack",
"action",
"active",
"add",
"after",
"all",
"allow",
"apple",
"auth",
"author",
"available",
"bad-protocol",
"bad-request",
"before",
"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",
"error",
"event",
"expiration",
"expired",
"fail",
"failure",
"false",
"favorites",
"feature",
"features",
"feature-not-implemented",
"field",
"first",
"free",
"from",
"g.us",
"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",
"missing",
"modify",
"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",
"platform",
"port",
"presence",
"preview",
"probe",
"prop",
"props",
"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",
"stat",
"status",
"stream:error",
"stream:features",
"subject",
"subscribe",
"success",
"sync",
"t",
"text",
"timeout",
"timestamp",
"to",
"true",
"type",
"unavailable",
"unsubscribe",
"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",
"value",
"version",
"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",
"Bell.caf",
"Boing.caf",
"Glass.caf",
"Harp.caf",
"TimePassing.caf",
"Tri-tone.caf",
"Xylophone.caf",
"background",
"backoff",
"chunked",
"context",
"full",
"in",
"interactive",
"out",
"registration",
"sid",
"urn:xmpp:whatsapp:sync",
"flt",
"s16",
"u8",
"adpcm",
"amrnb",
"amrwb",
"mp3",
"pcm",
"qcelp",
"wma",
"h263",
"h264",
"jpeg"
]
self.secondaryDictionary = [
"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",
"audio",
"clear",
"conflict",
"conn_no_nna",
"cost",
"currency",
"duration",
"extend",
"file",
"fps",
"g_notify",
"g_sound",
"gcm",
"gone",
"google_play",
"hash",
"height",
"invalid",
"jid-malformed",
"latitude",
"lc",
"lg",
"live",
"location",
"log",
"longitude",
"max_groups",
"max_participants",
"max_subject",
"mimetype",
"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",
"size",
"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",
"aurora.m4r",
"bamboo.m4r",
"chord.m4r",
"circles.m4r",
"complete.m4r",
"hello.m4r",
"input.m4r",
"keys.m4r",
"note.m4r",
"popcorn.m4r",
"pulse.m4r",
"synth.m4r",
"filehash",
"max_list_recipients",
"en-AU",
"en-GB",
"es-MX",
"pt-PT",
"zh-Hans",
"zh-Hant",
"relayelection",
"relaylatency",
"interruption",
"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",
"voip",
"eligible",
"upgrade",
"planned",
"current",
"future",
"disable",
"expire",
"start",
"stop",
"accuracy",
"speed",
"bearing",
"recording",
"encrypt",
"key",
"identity",
"w:gp2",
"admin",
"locked",
"unlocked",
"new",
"battery",
"archive",
"adm",
"plaintext_size",
"compressed_size",
"delivered",
"msg",
"pkmsg",
"everyone",
"v",
"transport",
"call-id"
]
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.4.48/yowsup/layers/interface/ 0000775 0000000 0000000 00000000000 12633464636 0020001 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/interface/__init__.py 0000664 0000000 0000000 00000000100 12633464636 0022101 0 ustar 00root root 0000000 0000000 from .interface import YowInterfaceLayer, ProtocolEntityCallback yowsup-2.4.48/yowsup/layers/interface/interface.py 0000664 0000000 0000000 00000007471 12633464636 0022324 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent
from yowsup.layers.protocol_iq.protocolentities import IqProtocolEntity
from yowsup.layers.network import YowNetworkLayer
from yowsup.layers.auth import YowAuthenticationProtocolLayer
from yowsup.layers.protocol_receipts.protocolentities import OutgoingReceiptProtocolEntity
from yowsup.layers.protocol_acks.protocolentities import IncomingAckProtocolEntity
import inspect
class ProtocolEntityCallback(object):
def __init__(self, entityType):
self.entityType = entityType
def __call__(self, fn):
fn.callback = self.entityType
return fn
class YowInterfaceLayer(YowLayer):
def __init__(self):
super(YowInterfaceLayer, self).__init__()
self.callbacks = {}
self.iqRegistry = {}
# self.receiptsRegistry = {}
members = inspect.getmembers(self, predicate=inspect.ismethod)
for m in members:
if hasattr(m[1], "callback"):
fname = m[0]
fn = m[1]
self.callbacks[fn.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 _sendReceipt(self, outgoingReceiptProtocolEntity, onAck = None):
# assert outgoingReceiptProtocolEntity.__class__ == OutgoingReceiptProtocolEntity,\
# "Excepted OutgoingReceiptProtocolEntity in _sendReceipt, got %s" % outgoingReceiptProtocolEntity.__class__
# self.receiptsRegistry[outgoingReceiptProtocolEntity.getId()] = (outgoingReceiptProtocolEntity, onAck)
# self.toLower(outgoingReceiptProtocolEntity)
# def processReceiptsRegistry(self, incomingAckProtocolEntity):
# '''
# entity: IncomingAckProtocolEntity
# '''
#
# if incomingAckProtocolEntity.__class__ != IncomingAckProtocolEntity:
# return False
#
# receipt_id = incomingAckProtocolEntity.getId()
# if receipt_id in self.receiptsRegistry:
# originalReceiptEntity, ackClbk = self.receiptsRegistry[receipt_id]
# del self.receiptsRegistry[receipt_id]
#
# if ackClbk:
# ackClbk(incomingAckProtocolEntity, originalReceiptEntity)
#
# return True
#
# return False
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.callbacks:
self.callbacks[entityType](entity)
else:
self.toUpper(entity)
def __str__(self):
return "Interface Layer"
yowsup-2.4.48/yowsup/layers/logger/ 0000775 0000000 0000000 00000000000 12633464636 0017320 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/logger/__init__.py 0000664 0000000 0000000 00000000042 12633464636 0021425 0 ustar 00root root 0000000 0000000 from .layer import YowLoggerLayer
yowsup-2.4.48/yowsup/layers/logger/layer.py 0000664 0000000 0000000 00000000753 12633464636 0021013 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.4.48/yowsup/layers/network/ 0000775 0000000 0000000 00000000000 12633464636 0017532 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/network/__init__.py 0000664 0000000 0000000 00000000043 12633464636 0021640 0 ustar 00root root 0000000 0000000 from .layer import YowNetworkLayer
yowsup-2.4.48/yowsup/layers/network/layer.py 0000664 0000000 0000000 00000007064 12633464636 0021227 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent
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"
def __init__(self):
YowLayer.__init__(self)
self.interface = YowNetworkLayerInterface(self)
asyncore.dispatcher.__init__(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
def onEvent(self, ev):
if ev.getName() == YowNetworkLayer.EVENT_STATE_CONNECT:
self.createConnection()
return True
elif ev.getName() == YowNetworkLayer.EVENT_STATE_DISCONNECT:
self.destroyConnection(ev.getArg("reason"))
return True
def createConnection(self):
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:
self.connect(endpoint)
def destroyConnection(self, reason = None):
self.handle_close(reason or "Requested")
def getStatus(self):
return self.connected
def handle_connect(self):
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"):
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.4.48/yowsup/layers/network/layer_interface.py 0000664 0000000 0000000 00000000440 12633464636 0023236 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.4.48/yowsup/layers/protocol_acks/ 0000775 0000000 0000000 00000000000 12633464636 0020703 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_acks/__init__.py 0000664 0000000 0000000 00000000047 12633464636 0023015 0 ustar 00root root 0000000 0000000 from .layer import YowAckProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_acks/layer.py 0000664 0000000 0000000 00000001021 12633464636 0022363 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.4.48/yowsup/layers/protocol_acks/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0024311 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_acks/protocolentities/__init__.py 0000664 0000000 0000000 00000000212 12633464636 0026415 0 ustar 00root root 0000000 0000000 from .ack import AckProtocolEntity
from .ack_incoming import IncomingAckProtocolEntity
from .ack_outgoing import OutgoingAckProtocolEntity yowsup-2.4.48/yowsup/layers/protocol_acks/protocolentities/ack.py 0000664 0000000 0000000 00000001743 12633464636 0025426 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.4.48/yowsup/layers/protocol_acks/protocolentities/ack_incoming.py 0000664 0000000 0000000 00000002430 12633464636 0027303 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.4.48/yowsup/layers/protocol_acks/protocolentities/ack_outgoing.py 0000664 0000000 0000000 00000003302 12633464636 0027332 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
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.4.48/yowsup/layers/protocol_acks/protocolentities/test_ack_incoming.py 0000664 0000000 0000000 00000000746 12633464636 0030352 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.4.48/yowsup/layers/protocol_acks/protocolentities/test_ack_outgoing.py 0000664 0000000 0000000 00000000705 12633464636 0030375 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.4.48/yowsup/layers/protocol_acks/test_layer.py 0000664 0000000 0000000 00000001124 12633464636 0023426 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.4.48/yowsup/layers/protocol_calls/ 0000775 0000000 0000000 00000000000 12633464636 0021060 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_calls/__init__.py 0000664 0000000 0000000 00000000051 12633464636 0023165 0 ustar 00root root 0000000 0000000 from .layer import YowCallsProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_calls/layer.py 0000664 0000000 0000000 00000002137 12633464636 0022551 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.4.48/yowsup/layers/protocol_calls/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0024466 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_calls/protocolentities/__init__.py 0000664 0000000 0000000 00000000066 12633464636 0026601 0 ustar 00root root 0000000 0000000 from .call import CallProtocolEntity
yowsup-2.4.48/yowsup/layers/protocol_calls/protocolentities/call.py 0000664 0000000 0000000 00000007365 12633464636 0025766 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.4.48/yowsup/layers/protocol_calls/protocolentities/test_call.py 0000664 0000000 0000000 00000001226 12633464636 0027013 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.4.48/yowsup/layers/protocol_chatstate/ 0000775 0000000 0000000 00000000000 12633464636 0021742 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_chatstate/__init__.py 0000664 0000000 0000000 00000000055 12633464636 0024053 0 ustar 00root root 0000000 0000000 from .layer import YowChatstateProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_chatstate/layer.py 0000664 0000000 0000000 00000001140 12633464636 0023424 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.4.48/yowsup/layers/protocol_chatstate/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025350 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_chatstate/protocolentities/__init__.py 0000664 0000000 0000000 00000000257 12633464636 0027465 0 ustar 00root root 0000000 0000000 from .chatstate import ChatstateProtocolEntity
from .chatstate_incoming import IncomingChatstateProtocolEntity
from .chatstate_outgoing import OutgoingChatstateProtocolEntity
yowsup-2.4.48/yowsup/layers/protocol_chatstate/protocolentities/chatstate.py 0000664 0000000 0000000 00000002322 12633464636 0027701 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.4.48/yowsup/layers/protocol_chatstate/protocolentities/chatstate_incoming.py 0000664 0000000 0000000 00000002316 12633464636 0031567 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.4.48/yowsup/layers/protocol_chatstate/protocolentities/chatstate_outgoing.py 0000664 0000000 0000000 00000002272 12633464636 0031620 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.4.48/yowsup/layers/protocol_chatstate/protocolentities/test_chatstate_incoming.py 0000664 0000000 0000000 00000001002 12633464636 0032615 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.4.48/yowsup/layers/protocol_chatstate/protocolentities/test_chatstate_outgoing.py 0000664 0000000 0000000 00000001002 12633464636 0032645 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.4.48/yowsup/layers/protocol_chatstate/test_layer.py 0000664 0000000 0000000 00000001366 12633464636 0024475 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.4.48/yowsup/layers/protocol_contacts/ 0000775 0000000 0000000 00000000000 12633464636 0021600 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_contacts/__init__.py 0000664 0000000 0000000 00000000055 12633464636 0023711 0 ustar 00root root 0000000 0000000 from .layer import YowContactsIqProtocolLayer yowsup-2.4.48/yowsup/layers/protocol_contacts/layer.py 0000664 0000000 0000000 00000003320 12633464636 0023264 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.4.48/yowsup/layers/protocol_contacts/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025206 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_contacts/protocolentities/__init__.py 0000664 0000000 0000000 00000001107 12633464636 0027316 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.4.48/yowsup/layers/protocol_contacts/protocolentities/iq_statuses_get.py 0000664 0000000 0000000 00000003104 12633464636 0030761 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/protocol_contacts/protocolentities/iq_statuses_result.py 0000664 0000000 0000000 00000003774 12633464636 0031535 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)
setResultStatusesProps(statusesp)
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.iteritems())
return out
def toProtocolTreeNode(self):
node = super(ResultStatusesIqProtocolEntity, self).toProtcolTreeNode()
users = [ProtocolTreeNode('user', {'jid': jid, 't': t}, None, status) for jid, (status, t) in self.statuses.iteritems()]
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.4.48/yowsup/layers/protocol_contacts/protocolentities/iq_sync.py 0000664 0000000 0000000 00000003557 12633464636 0027237 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.4.48/yowsup/layers/protocol_contacts/protocolentities/iq_sync_get.py 0000664 0000000 0000000 00000005274 12633464636 0030074 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.4.48/yowsup/layers/protocol_contacts/protocolentities/iq_sync_result.py 0000664 0000000 0000000 00000007632 12633464636 0030633 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.4.48/yowsup/layers/protocol_contacts/protocolentities/notification_contact.py 0000664 0000000 0000000 00000001454 12633464636 0031765 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.4.48/yowsup/layers/protocol_contacts/protocolentities/notification_contact_add.py 0000664 0000000 0000000 00000002367 12633464636 0032601 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.4.48/yowsup/layers/protocol_contacts/protocolentities/notification_contact_remove.py 0000664 0000000 0000000 00000002417 12633464636 0033342 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.4.48/yowsup/layers/protocol_contacts/protocolentities/notification_contact_update.py 0000664 0000000 0000000 00000002417 12633464636 0033327 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.4.48/yowsup/layers/protocol_contacts/protocolentities/notificiation_contacts_sync.py 0000664 0000000 0000000 00000002325 12633464636 0033353 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.4.48/yowsup/layers/protocol_contacts/protocolentities/test_iq_sync_get.py 0000664 0000000 0000000 00000000661 12633464636 0031126 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.4.48/yowsup/layers/protocol_contacts/protocolentities/test_iq_sync_result.py 0000664 0000000 0000000 00000001370 12633464636 0031663 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.4.48/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_add.py 0000664 0000000 0000000 00000001240 12633464636 0033625 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.4.48/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_remove.py 0000664 0000000 0000000 00000001145 12633464636 0034376 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.4.48/yowsup/layers/protocol_contacts/protocolentities/test_notification_contact_update.py 0000664 0000000 0000000 00000001144 12633464636 0034362 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.4.48/yowsup/layers/protocol_contacts/test_layer.py 0000664 0000000 0000000 00000002300 12633464636 0024320 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.4.48/yowsup/layers/protocol_groups/ 0000775 0000000 0000000 00000000000 12633464636 0021301 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_groups/__init__.py 0000664 0000000 0000000 00000000052 12633464636 0023407 0 ustar 00root root 0000000 0000000 from .layer import YowGroupsProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_groups/layer.py 0000664 0000000 0000000 00000013403 12633464636 0022770 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent, YowProtocolLayer
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")
def onSetSubjectSuccess(self, node, originalIqEntity):
logger.info("Group subject change success")
def onSetSubjectFailed(self, node, originalIqEntity):
logger.error("Group subject change failed")
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")
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")
def onPromoteParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group promote participants success")
def onDemoteParticipantsFailed(self, node, originalIqEntity):
logger.error("Group demote participants failed")
def onDemoteParticipantsSuccess(self, node, originalIqEntity):
logger.info("Group demote participants success")
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")
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")
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.4.48/yowsup/layers/protocol_groups/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0024707 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_groups/protocolentities/__init__.py 0000664 0000000 0000000 00000003252 12633464636 0027022 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups.py 0000664 0000000 0000000 00000000707 12633464636 0027275 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_create.py 0000664 0000000 0000000 00000003336 12633464636 0030621 0 ustar 00root root 0000000 0000000 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 = "g.us", _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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_create_success.py 0000664 0000000 0000000 00000002064 12633464636 0032346 0 ustar 00root root 0000000 0000000 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 = "g.us", _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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_info.py 0000664 0000000 0000000 00000002421 12633464636 0030303 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_leave.py 0000664 0000000 0000000 00000003214 12633464636 0030445 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .iq_groups import GroupsIqProtocolEntity
class LeaveGroupsIqProtocolEntity(GroupsIqProtocolEntity):
'''
'''
def __init__(self, groupList):
super(LeaveGroupsIqProtocolEntity, self).__init__(to = "g.us", _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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_leave_success.py 0000664 0000000 0000000 00000002620 12633464636 0032175 0 ustar 00root root 0000000 0000000 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="g.us", _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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_list.py 0000664 0000000 0000000 00000004104 12633464636 0030323 0 ustar 00root root 0000000 0000000 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 = "g.us", _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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants.py 0000664 0000000 0000000 00000003151 12633464636 0032052 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add.py 0000664 0000000 0000000 00000002101 12633464636 0032654 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add_failure.py 0000664 0000000 0000000 00000001516 12633464636 0034374 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_add_success.py 0000664 0000000 0000000 00000003371 12633464636 0034416 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_demote.py 0000664 0000000 0000000 00000002141 12633464636 0033405 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_promote.py 0000664 0000000 0000000 00000002152 12633464636 0033617 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_participants_remove.py 0000664 0000000 0000000 00000002150 12633464636 0033425 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
iq_groups_participants_remove_success.py 0000664 0000000 0000000 00000003435 12633464636 0035105 0 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_groups/protocolentities 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_groups_subject.py 0000664 0000000 0000000 00000002064 12633464636 0031012 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_result_groups_info.py 0000664 0000000 0000000 00000010240 12633464636 0031677 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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_result_groups_list.py 0000664 0000000 0000000 00000006371 12633464636 0031731 0 ustar 00root root 0000000 0000000 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 = "g.us")
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.4.48/yowsup/layers/protocol_groups/protocolentities/iq_result_participants_list.py 0000664 0000000 0000000 00000003134 12633464636 0033105 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.4.48/yowsup/layers/protocol_groups/protocolentities/notification_groups.py 0000664 0000000 0000000 00000003314 12633464636 0031347 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.4.48/yowsup/layers/protocol_groups/protocolentities/notification_groups_add.py 0000664 0000000 0000000 00000003632 12633464636 0032162 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.4.48/yowsup/layers/protocol_groups/protocolentities/notification_groups_create.py 0000664 0000000 0000000 00000011263 12633464636 0032674 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.4.48/yowsup/layers/protocol_groups/protocolentities/notification_groups_remove.py 0000664 0000000 0000000 00000004065 12633464636 0032730 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 dict, "Participants must be a dict {jid => type?}"
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[p["jid"]] = p["type"]
return RemoveGroupsNotificationProtocolEntity(
node["id"], node["from"], node["t"], node["notify"], node["participant"], node["offline"],
removeNode["subject"], participants
)
yowsup-2.4.48/yowsup/layers/protocol_groups/protocolentities/notification_groups_subject.py 0000664 0000000 0000000 00000004400 12633464636 0033063 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.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_groups.py 0000664 0000000 0000000 00000000226 12633464636 0030330 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq import IqProtocolEntityTest
class GroupsIqProtocolEntityTest(IqProtocolEntityTest):
pass
yowsup-2.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_create.py 0000664 0000000 0000000 00000000676 12633464636 0031664 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.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_create_success.py 0000664 0000000 0000000 00000000716 12633464636 0033407 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.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_groups_list.py 0000664 0000000 0000000 00000000645 12633464636 0031370 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.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_result_groups.py 0000664 0000000 0000000 00000000256 12633464636 0031731 0 ustar 00root root 0000000 0000000 from yowsup.layers.protocol_iq.protocolentities.test_iq_result import ResultIqProtocolEntityTest
class GroupsResultIqProtocolEntityTest(ResultIqProtocolEntityTest):
pass yowsup-2.4.48/yowsup/layers/protocol_groups/protocolentities/test_iq_result_groups_list.py 0000664 0000000 0000000 00000001420 12633464636 0032756 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.4.48/yowsup/layers/protocol_groups/structs/ 0000775 0000000 0000000 00000000000 12633464636 0023010 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_groups/structs/__init__.py 0000664 0000000 0000000 00000000030 12633464636 0025112 0 ustar 00root root 0000000 0000000 from .group import Group yowsup-2.4.48/yowsup/layers/protocol_groups/structs/group.py 0000664 0000000 0000000 00000002407 12633464636 0024521 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.4.48/yowsup/layers/protocol_ib/ 0000775 0000000 0000000 00000000000 12633464636 0020354 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_ib/__init__.py 0000664 0000000 0000000 00000000047 12633464636 0022466 0 ustar 00root root 0000000 0000000 from .layer import YowIbProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_ib/layer.py 0000664 0000000 0000000 00000001721 12633464636 0022043 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.4.48/yowsup/layers/protocol_ib/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0023762 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_ib/protocolentities/__init__.py 0000664 0000000 0000000 00000000267 12633464636 0026100 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.4.48/yowsup/layers/protocol_ib/protocolentities/account_ib.py 0000664 0000000 0000000 00000003714 12633464636 0026447 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.4.48/yowsup/layers/protocol_ib/protocolentities/clean_iq.py 0000664 0000000 0000000 00000002421 12633464636 0026106 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.4.48/yowsup/layers/protocol_ib/protocolentities/dirty_ib.py 0000664 0000000 0000000 00000002401 12633464636 0026136 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.4.48/yowsup/layers/protocol_ib/protocolentities/ib.py 0000664 0000000 0000000 00000000715 12633464636 0024731 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.4.48/yowsup/layers/protocol_ib/protocolentities/offline_ib.py 0000664 0000000 0000000 00000002050 12633464636 0026425 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.4.48/yowsup/layers/protocol_ib/protocolentities/test_clean_iq.py 0000664 0000000 0000000 00000000765 12633464636 0027156 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.4.48/yowsup/layers/protocol_ib/protocolentities/test_dirty_ib.py 0000664 0000000 0000000 00000001057 12633464636 0027203 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.4.48/yowsup/layers/protocol_ib/protocolentities/test_ib.py 0000664 0000000 0000000 00000000567 12633464636 0025775 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.4.48/yowsup/layers/protocol_ib/protocolentities/test_offline_iq.py 0000664 0000000 0000000 00000000736 12633464636 0027514 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.4.48/yowsup/layers/protocol_iq/ 0000775 0000000 0000000 00000000000 12633464636 0020373 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_iq/__init__.py 0000664 0000000 0000000 00000000045 12633464636 0022503 0 ustar 00root root 0000000 0000000 from .layer import YowIqProtocolLayer yowsup-2.4.48/yowsup/layers/protocol_iq/layer.py 0000664 0000000 0000000 00000007327 12633464636 0022072 0 ustar 00root root 0000000 0000000 import time
import logging
from threading import Thread, Lock
from yowsup.layers import YowProtocolLayer, YowLayerEvent
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"))
def onEvent(self, event):
name = event.getName()
if name == YowAuthenticationProtocolLayer.EVENT_AUTHED:
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()
elif name == YowNetworkLayer.EVENT_STATE_DISCONNECT or name == YowNetworkLayer.EVENT_STATE_DISCONNECTED:
if self._pingThread:
self.__logger.debug("stopping ping thread")
if self._pingThread:
self._pingThread.stop()
self._pingThread = None
self._pingQueue = {}
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.4.48/yowsup/layers/protocol_iq/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0024001 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_iq/protocolentities/__init__.py 0000664 0000000 0000000 00000000540 12633464636 0026111 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq.py 0000664 0000000 0000000 00000004331 12633464636 0024765 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_crypto.py 0000664 0000000 0000000 00000001213 12633464636 0026361 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_error.py 0000664 0000000 0000000 00000003155 12633464636 0026201 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_ping.py 0000664 0000000 0000000 00000001053 12633464636 0026000 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_props.py 0000664 0000000 0000000 00000000610 12633464636 0026204 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_push.py 0000664 0000000 0000000 00000000633 12633464636 0026025 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_result.py 0000664 0000000 0000000 00000000641 12633464636 0026363 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.4.48/yowsup/layers/protocol_iq/protocolentities/iq_result_pong.py 0000664 0000000 0000000 00000000604 12633464636 0027405 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.4.48/yowsup/layers/protocol_iq/protocolentities/test_iq.py 0000664 0000000 0000000 00000000671 12633464636 0026027 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.4.48/yowsup/layers/protocol_iq/protocolentities/test_iq_error.py 0000664 0000000 0000000 00000000771 12633464636 0027241 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.4.48/yowsup/layers/protocol_iq/protocolentities/test_iq_result.py 0000664 0000000 0000000 00000000411 12633464636 0027415 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.4.48/yowsup/layers/protocol_media/ 0000775 0000000 0000000 00000000000 12633464636 0021041 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_media/__init__.py 0000664 0000000 0000000 00000000052 12633464636 0023147 0 ustar 00root root 0000000 0000000 from .layer import YowMediaProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_media/layer.py 0000664 0000000 0000000 00000006600 12633464636 0022531 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.4.48/yowsup/layers/protocol_media/mediadownloader.py 0000664 0000000 0000000 00000004013 12633464636 0024547 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.4.48/yowsup/layers/protocol_media/mediauploader.py 0000664 0000000 0000000 00000012010 12633464636 0024220 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
import socket, ssl, mimetypes, os, hashlib, sys
from time import sleep
import threading
import logging
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 = mimetypes.guess_type(filename)[0]
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.4.48/yowsup/layers/protocol_media/picture.py 0000664 0000000 0000000 00000002073 12633464636 0023070 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.4.48/yowsup/layers/protocol_media/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0024447 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_media/protocolentities/__init__.py 0000664 0000000 0000000 00000001240 12633464636 0026555 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.4.48/yowsup/layers/protocol_media/protocolentities/iq_requestupload.py 0000664 0000000 0000000 00000006112 12633464636 0030407 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/protocol_media/protocolentities/iq_requestupload_result.py 0000664 0000000 0000000 00000004161 12633464636 0032007 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/protocol_media/protocolentities/message_media.py 0000664 0000000 0000000 00000016350 12633464636 0027611 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.4.48/yowsup/layers/protocol_media/protocolentities/message_media_downloadable.py 0000664 0000000 0000000 00000007170 12633464636 0032324 0 ustar 00root root 0000000 0000000 from .message_media import MediaMessageProtocolEntity
from yowsup.common.tools import WATools
import mimetypes
import os
class DownloadableMediaMessageProtocolEntity(MediaMessageProtocolEntity):
'''
{{THUMBNAIL_RAWDATA (JPEG?)}}
'''
def __init__(self, mediaType,
mimeType, fileHash, url, ip, size, fileName,
_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)
def __str__(self):
out = super(DownloadableMediaMessageProtocolEntity, self).__str__()
out += "MimeType: %s\n" % self.mimeType
out += "File Hash: %s\n" % self.fileHash
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):
self.mimeType = mimeType
self.fileHash = fileHash
self.url = url
self.ip = ip
self.size = int(size)
self.fileName = fileName
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)
return node
@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")
)
return entity
@staticmethod
def fromFilePath(fpath, url, mediaType, ip, to, mimeType = None, preview = None, filehash = None, filesize = None):
mimeType = mimeType or mimetypes.guess_type(fpath)[0]
filehash = filehash or WATools.getFileHashForUpload(fpath)
size = filesize or os.path.getsize(fpath)
fileName = os.path.basename(fpath)
return DownloadableMediaMessageProtocolEntity(mediaType, mimeType, filehash, url, ip, size, fileName, to = to, preview = preview)
yowsup-2.4.48/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_audio.py 0000664 0000000 0000000 00000010205 12633464636 0033476 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,
_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.4.48/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_image.py 0000664 0000000 0000000 00000007264 12633464636 0033472 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
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,
_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,
_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
@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 fromFilePath(path, url, ip, to, mimeType = None, caption = None, dimensions = None):
preview = ImageTools.generatePreviewFromImage(path)
entity = DownloadableMediaMessageProtocolEntity.fromFilePath(path, url, DownloadableMediaMessageProtocolEntity.MEDIA_TYPE_IMAGE, ip, to, mimeType, preview)
entity.__class__ = ImageDownloadableMediaMessageProtocolEntity
if not dimensions:
dimensions = ImageTools.getImageDimensions(path)
assert dimensions, "Could not determine image dimensions"
width, height = dimensions
entity.setImageProps("raw", width, height, caption)
return entity
yowsup-2.4.48/yowsup/layers/protocol_media/protocolentities/message_media_downloadable_video.py 0000664 0000000 0000000 00000011751 12633464636 0033512 0 ustar 00root root 0000000 0000000 from yowsup.structs import ProtocolEntity, ProtocolTreeNode
from .message_media_downloadable import DownloadableMediaMessageProtocolEntity
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,
_id, _from, to, notify, timestamp, participant, preview, offline, retry)
self.setVideoProps(abitrate, acodec, asampfmt, asampfreq, duration, encoding, fps, width, height, seconds, vbitrate, 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, abitrate, acodec, asampfmt, asampfreq, duration, encoding, fps, width, height, seconds, vbitrate, vcodec, 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("fps", self.fps)
mediaNode.setAttribute("height", self.height)
if self.seconds is not None:
mediaNode.setAttribute("seconds", self.seconds)
if self.vbitrate is not None:
mediaNode.setAttribute("vbitrate", self.vbitrate)
mediaNode.setAttribute("vcodec", self.vcodec)
mediaNode.setAttribute("width", self.width)
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("abitrate"),
mediaNode.getAttributeValue("acodec"),
mediaNode.getAttributeValue("asampfmt"),
mediaNode.getAttributeValue("asampfreq"),
mediaNode.getAttributeValue("duration"),
mediaNode.getAttributeValue("encoding"),
mediaNode.getAttributeValue("fps"),
mediaNode.getAttributeValue("width"),
mediaNode.getAttributeValue("height"),
mediaNode.getAttributeValue("seconds"),
mediaNode.getAttributeValue("vbitrate"),
mediaNode.getAttributeValue("vcodec"),
mediaNode.getAttributeValue("caption")
)
return entity
yowsup-2.4.48/yowsup/layers/protocol_media/protocolentities/message_media_location.py 0000664 0000000 0000000 00000005611 12633464636 0031477 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.4.48/yowsup/layers/protocol_media/protocolentities/message_media_vcard.py 0000664 0000000 0000000 00000012271 12633464636 0030766 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.4.48/yowsup/layers/protocol_media/protocolentities/test_iq_requestupload.py 0000664 0000000 0000000 00000001163 12633464636 0031447 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.4.48/yowsup/layers/protocol_media/protocolentities/test_iq_requestupload_result.py 0000664 0000000 0000000 00000001106 12633464636 0033042 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media.py 0000664 0000000 0000000 00000001066 12633464636 0030646 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable.py 0000664 0000000 0000000 00000001511 12633464636 0033354 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_audio.py0000664 0000000 0000000 00000001644 12633464636 0034544 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_image.py0000664 0000000 0000000 00000001441 12633464636 0034520 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_downloadable_video.py0000664 0000000 0000000 00000002261 12633464636 0034545 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_location.py 0000664 0000000 0000000 00000001261 12633464636 0032533 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.4.48/yowsup/layers/protocol_media/protocolentities/test_message_media_vcard.py 0000664 0000000 0000000 00000001235 12633464636 0032023 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.4.48/yowsup/layers/protocol_messages/ 0000775 0000000 0000000 00000000000 12633464636 0021571 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_messages/__init__.py 0000664 0000000 0000000 00000000054 12633464636 0023701 0 ustar 00root root 0000000 0000000 from .layer import YowMessagesProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_messages/layer.py 0000664 0000000 0000000 00000001421 12633464636 0023255 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.4.48/yowsup/layers/protocol_messages/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025177 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_messages/protocolentities/__init__.py 0000664 0000000 0000000 00000000230 12633464636 0027303 0 ustar 00root root 0000000 0000000 from .message_text import TextMessageProtocolEntity
from .message import MessageProtocolEntity
from .message_text_broadcast import BroadcastTextMessage
yowsup-2.4.48/yowsup/layers/protocol_messages/protocolentities/message.py 0000664 0000000 0000000 00000010173 12633464636 0027177 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 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.4.48/yowsup/layers/protocol_messages/protocolentities/message_text.py 0000664 0000000 0000000 00000002652 12633464636 0030246 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.4.48/yowsup/layers/protocol_messages/protocolentities/message_text_broadcast.py 0000664 0000000 0000000 00000002241 12633464636 0032262 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.4.48/yowsup/layers/protocol_messages/protocolentities/test_message.py 0000664 0000000 0000000 00000001317 12633464636 0030236 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.4.48/yowsup/layers/protocol_messages/protocolentities/test_message_text.py 0000664 0000000 0000000 00000001045 12633464636 0031300 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.4.48/yowsup/layers/protocol_messages/protocolentities/test_message_text_broadcast.py 0000664 0000000 0000000 00000001264 12633464636 0033325 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.4.48/yowsup/layers/protocol_notifications/ 0000775 0000000 0000000 00000000000 12633464636 0022633 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_notifications/__init__.py 0000664 0000000 0000000 00000000060 12633464636 0024740 0 ustar 00root root 0000000 0000000 from .layer import YowNotificationsProtocolLayer yowsup-2.4.48/yowsup/layers/protocol_notifications/layer.py 0000664 0000000 0000000 00000003372 12633464636 0024326 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.4.48/yowsup/layers/protocol_notifications/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0026241 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_notifications/protocolentities/__init__.py 0000664 0000000 0000000 00000000605 12633464636 0030353 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.4.48/yowsup/layers/protocol_notifications/protocolentities/notification.py 0000664 0000000 0000000 00000004020 12633464636 0031275 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.4.48/yowsup/layers/protocol_notifications/protocolentities/notification_picture.py 0000664 0000000 0000000 00000001457 12633464636 0033043 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.4.48/yowsup/layers/protocol_notifications/protocolentities/notification_picture_delete.py 0000664 0000000 0000000 00000002726 12633464636 0034365 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.4.48/yowsup/layers/protocol_notifications/protocolentities/notification_picture_set.py 0000664 0000000 0000000 00000002575 12633464636 0033720 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.4.48/yowsup/layers/protocol_notifications/protocolentities/notification_status.py 0000664 0000000 0000000 00000002303 12633464636 0032702 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.4.48/yowsup/layers/protocol_notifications/protocolentities/test_notification.py 0000664 0000000 0000000 00000001226 12633464636 0032341 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.4.48/yowsup/layers/protocol_notifications/protocolentities/test_notification_picture.py 0000664 0000000 0000000 00000000722 12633464636 0034074 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 12633464636 0035341 0 ustar 00root root 0000000 0000000 yowsup-2.4.48/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.4.48/yowsup/layers/protocol_notifications/protocolentities/test_notification_picture_set.py0000664 0000000 0000000 00000001237 12633464636 0034751 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.4.48/yowsup/layers/protocol_notifications/protocolentities/test_notification_status.py 0000664 0000000 0000000 00000001136 12633464636 0033744 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.4.48/yowsup/layers/protocol_presence/ 0000775 0000000 0000000 00000000000 12633464636 0021566 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_presence/__init__.py 0000664 0000000 0000000 00000000054 12633464636 0023676 0 ustar 00root root 0000000 0000000 from .layer import YowPresenceProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_presence/layer.py 0000664 0000000 0000000 00000002227 12633464636 0023257 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.4.48/yowsup/layers/protocol_presence/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025174 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_presence/protocolentities/__init__.py 0000664 0000000 0000000 00000000710 12633464636 0027303 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.4.48/yowsup/layers/protocol_presence/protocolentities/iq_lastseen.py 0000664 0000000 0000000 00000001307 12633464636 0030056 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.4.48/yowsup/layers/protocol_presence/protocolentities/iq_lastseen_result.py 0000664 0000000 0000000 00000002004 12633464636 0031447 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.4.48/yowsup/layers/protocol_presence/protocolentities/presence.py 0000664 0000000 0000000 00000003611 12633464636 0027353 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.4.48/yowsup/layers/protocol_presence/protocolentities/presence_available.py 0000664 0000000 0000000 00000000603 12633464636 0031351 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.4.48/yowsup/layers/protocol_presence/protocolentities/presence_subscribe.py 0000664 0000000 0000000 00000002011 12633464636 0031405 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.4.48/yowsup/layers/protocol_presence/protocolentities/presence_unavailable.py 0000664 0000000 0000000 00000000635 12633464636 0031721 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.4.48/yowsup/layers/protocol_presence/protocolentities/presence_unsubscribe.py 0000664 0000000 0000000 00000002027 12633464636 0031757 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.4.48/yowsup/layers/protocol_presence/protocolentities/test_presence.py 0000664 0000000 0000000 00000000733 12633464636 0030414 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.4.48/yowsup/layers/protocol_presence/protocolentities/test_presence_available.py 0000664 0000000 0000000 00000000746 12633464636 0032420 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.4.48/yowsup/layers/protocol_presence/protocolentities/test_presence_subscribe.py 0000664 0000000 0000000 00000001033 12633464636 0032447 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.4.48/yowsup/layers/protocol_presence/protocolentities/test_presence_unavailable.py 0000664 0000000 0000000 00000000762 12633464636 0032761 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.4.48/yowsup/layers/protocol_presence/protocolentities/test_presence_unsubscribe.py 0000664 0000000 0000000 00000001042 12633464636 0033012 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.4.48/yowsup/layers/protocol_privacy/ 0000775 0000000 0000000 00000000000 12633464636 0021437 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_privacy/__init__.py 0000664 0000000 0000000 00000000052 12633464636 0023545 0 ustar 00root root 0000000 0000000 from .layer import YowPrivacyProtocolLayer yowsup-2.4.48/yowsup/layers/protocol_privacy/layer.py 0000664 0000000 0000000 00000001027 12633464636 0023125 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.4.48/yowsup/layers/protocol_privacy/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025045 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_privacy/protocolentities/__init__.py 0000664 0000000 0000000 00000000067 12633464636 0027161 0 ustar 00root root 0000000 0000000 from .privacylist_iq import PrivacyListIqProtocolEntity yowsup-2.4.48/yowsup/layers/protocol_privacy/protocolentities/privacylist_iq.py 0000664 0000000 0000000 00000001727 12633464636 0030470 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.4.48/yowsup/layers/protocol_profiles/ 0000775 0000000 0000000 00000000000 12633464636 0021605 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_profiles/__init__.py 0000664 0000000 0000000 00000000053 12633464636 0023714 0 ustar 00root root 0000000 0000000 from .layer import YowProfilesProtocolLayer yowsup-2.4.48/yowsup/layers/protocol_profiles/layer.py 0000664 0000000 0000000 00000005237 12633464636 0023302 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.4.48/yowsup/layers/protocol_profiles/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025213 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_profiles/protocolentities/__init__.py 0000664 0000000 0000000 00000001003 12633464636 0027316 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_picture.py 0000664 0000000 0000000 00000001036 12633464636 0027731 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_picture_get.py 0000664 0000000 0000000 00000002216 12633464636 0030571 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_picture_get_result.py 0000664 0000000 0000000 00000003346 12633464636 0032174 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_picture_set.py 0000664 0000000 0000000 00000004440 12633464636 0030606 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_pictures_list.py 0000664 0000000 0000000 00000002502 12633464636 0031146 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_get.py 0000664 0000000 0000000 00000001627 12633464636 0030600 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_result.py 0000664 0000000 0000000 00000003267 12633464636 0031341 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_privacy_set.py 0000664 0000000 0000000 00000005002 12633464636 0030603 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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_status_set.py 0000664 0000000 0000000 00000002114 12633464636 0030452 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/protocol_profiles/protocolentities/iq_unregister.py 0000664 0000000 0000000 00000001651 12633464636 0030450 0 ustar 00root root 0000000 0000000 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 = "s.whatsapp.net")
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.4.48/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_get.py 0000664 0000000 0000000 00000000766 12633464636 0031642 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.4.48/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_result.py 0000664 0000000 0000000 00000001070 12633464636 0032366 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.4.48/yowsup/layers/protocol_profiles/protocolentities/test_iq_privacy_set.py 0000664 0000000 0000000 00000001030 12633464636 0031637 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.4.48/yowsup/layers/protocol_profiles/protocolentities/test_iq_status_set.py 0000664 0000000 0000000 00000001033 12633464636 0031510 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.4.48/yowsup/layers/protocol_profiles/protocolentities/test_iq_unregister.py 0000664 0000000 0000000 00000000775 12633464636 0031515 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.4.48/yowsup/layers/protocol_receipts/ 0000775 0000000 0000000 00000000000 12633464636 0021600 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_receipts/__init__.py 0000664 0000000 0000000 00000000054 12633464636 0023710 0 ustar 00root root 0000000 0000000 from .layer import YowReceiptProtocolLayer
yowsup-2.4.48/yowsup/layers/protocol_receipts/layer.py 0000664 0000000 0000000 00000001117 12633464636 0023266 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.4.48/yowsup/layers/protocol_receipts/protocolentities/ 0000775 0000000 0000000 00000000000 12633464636 0025206 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/protocol_receipts/protocolentities/__init__.py 0000664 0000000 0000000 00000000242 12633464636 0027315 0 ustar 00root root 0000000 0000000 from .receipt import ReceiptProtocolEntity
from .receipt_incoming import IncomingReceiptProtocolEntity
from .receipt_outgoing import OutgoingReceiptProtocolEntity yowsup-2.4.48/yowsup/layers/protocol_receipts/protocolentities/receipt.py 0000664 0000000 0000000 00000002033 12633464636 0027211 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.4.48/yowsup/layers/protocol_receipts/protocolentities/receipt_incoming.py 0000664 0000000 0000000 00000010732 12633464636 0031101 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):
return self.participant
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())
@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.4.48/yowsup/layers/protocol_receipts/protocolentities/receipt_outgoing.py 0000664 0000000 0000000 00000005574 12633464636 0031141 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.4.48/yowsup/layers/protocol_receipts/protocolentities/test_receipt_incoming.py 0000664 0000000 0000000 00000000700 12633464636 0032132 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.4.48/yowsup/layers/protocol_receipts/protocolentities/test_receipt_outgoing.py 0000664 0000000 0000000 00000000651 12633464636 0032167 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.4.48/yowsup/layers/stanzaregulator/ 0000775 0000000 0000000 00000000000 12633464636 0021266 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/layers/stanzaregulator/__init__.py 0000664 0000000 0000000 00000000045 12633464636 0023376 0 ustar 00root root 0000000 0000000 from .layer import YowStanzaRegulator yowsup-2.4.48/yowsup/layers/stanzaregulator/layer.py 0000664 0000000 0000000 00000003073 12633464636 0022757 0 ustar 00root root 0000000 0000000 from yowsup.layers import YowLayer, YowLayerEvent
from yowsup.layers.network import YowNetworkLayer
class YowStanzaRegulator(YowLayer):
'''
send: bytearray -> bytearray
receive: bytearray -> bytearray
'''
def __init__(self):
super(YowLayer, self).__init__()
self.buf = bytearray()
self.enabled = False
def onEvent(self, yowLayerEvent):
if yowLayerEvent.getName() == YowNetworkLayer.EVENT_STATE_CONNECTED:
self.enabled = True
self.buf = bytearray()
elif yowLayerEvent.getName() == YowNetworkLayer.EVENT_STATE_DISCONNECTED:
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.4.48/yowsup/registration/ 0000775 0000000 0000000 00000000000 12633464636 0017254 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/registration/__init__.py 0000664 0000000 0000000 00000000166 12633464636 0021370 0 ustar 00root root 0000000 0000000 from .coderequest import WACodeRequest
from .existsrequest import WAExistsRequest
from .regrequest import WARegRequest yowsup-2.4.48/yowsup/registration/coderequest.py 0000664 0000000 0000000 00000003404 12633464636 0022152 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
# from yowsup.env import CURRENT_ENV
from yowsup.common.tools import StorageTools, WATools
from yowsup.registration.existsrequest import WAExistsRequest
from yowsup.env import S40YowsupEnv
CURRENT_ENV = S40YowsupEnv()
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("method", method)
self.addParam("token", CURRENT_ENV.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
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.4.48/yowsup/registration/existsrequest.py 0000664 0000000 0000000 00000001645 12633464636 0022564 0 ustar 00root root 0000000 0000000 from yowsup.common.http.warequest import WARequest
from yowsup.common.http.waresponseparser import JSONResponseParser
from yowsup.env import CURRENT_ENV
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", CURRENT_ENV.getToken(p_in))
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.4.48/yowsup/registration/regrequest.py 0000664 0000000 0000000 00000003676 12633464636 0022030 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
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.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.4.48/yowsup/stacks/ 0000775 0000000 0000000 00000000000 12633464636 0016032 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/stacks/__init__.py 0000664 0000000 0000000 00000005114 12633464636 0020144 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.4.48/yowsup/stacks/yowstack.py 0000664 0000000 0000000 00000020540 12633464636 0020251 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 import env
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
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 YowAxolotlLayer
allLayers += (YowAxolotlLayer,)
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, env.CURRENT_ENV.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.4.48/yowsup/structs/ 0000775 0000000 0000000 00000000000 12633464636 0016251 5 ustar 00root root 0000000 0000000 yowsup-2.4.48/yowsup/structs/__init__.py 0000664 0000000 0000000 00000000131 12633464636 0020355 0 ustar 00root root 0000000 0000000 from .protocolentity import ProtocolEntity
from .protocoltreenode import ProtocolTreeNode yowsup-2.4.48/yowsup/structs/protocolentity.py 0000664 0000000 0000000 00000002702 12633464636 0021722 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.4.48/yowsup/structs/protocoltreenode.py 0000664 0000000 0000000 00000011212 12633464636 0022207 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():
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