diff -Nru google-tasks-indicator-0.0.3.2~quantal/COPYING google-tasks-indicator-0.0.5.1.quantal.1/COPYING --- google-tasks-indicator-0.0.3.2~quantal/COPYING 2011-09-10 16:58:48.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/COPYING 1970-01-01 00:00:00.000000000 +0000 @@ -1,674 +0,0 @@ - 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. - - - Copyright (C) - - 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: - - Copyright (C) - 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 -. diff -Nru google-tasks-indicator-0.0.3.2~quantal/Google-Tasks-Indicator.desktop.in google-tasks-indicator-0.0.5.1.quantal.1/Google-Tasks-Indicator.desktop.in --- google-tasks-indicator-0.0.3.2~quantal/Google-Tasks-Indicator.desktop.in 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/Google-Tasks-Indicator.desktop.in 2013-01-19 06:20:23.000000000 +0000 @@ -0,0 +1,56 @@ +[Desktop Entry] +Encoding = UTF-8 +_Name = Google-Taks-Indicator +Version = 0.0.4.0 +_Comment = An indicator for Google Tasks +_GenericName = Google-Tasks-Indicator +Terminal = false +Icon = /usr/share/google-tasks-indicator/icons/google-tasks-indicator.svg +Type = Application +Exec = /usr/bin/google-tasks-indicator +$Name[it] = _('Google-Taks-Indicator') +$Name[fr] = _('Google-Taks-Indicator') +$Name[es] = _('Google-Taks-Indicator') +$Name[tr] = _('Google-Taks-Indicator') +$Name[de] = _('Google-Taks-Indicator') +$Name[zh_CN] = _('Google-Taks-Indicator') +$Name[fi] = _('Google-Taks-Indicator') +$Name[ru] = _('Google-Taks-Indicator') +$Comment[it] = _('An indicator for Google Tasks') +$Comment[fr] = _('An indicator for Google Tasks') +$Comment[es] = _('An indicator for Google Tasks') +$Comment[tr] = _('An indicator for Google Tasks') +$Comment[de] = _('An indicator for Google Tasks') +$Comment[zh_CN] = _('An indicator for Google Tasks') +$Comment[fi] = _('An indicator for Google Tasks') +$Comment[ru] = _('An indicator for Google Tasks') +$GenericName[it] = _('Google-Tasks-Indicator') +$GenericName[fr] = _('Google-Tasks-Indicator') +$GenericName[es] = _('Google-Tasks-Indicator') +$GenericName[tr] = _('Google-Tasks-Indicator') +$GenericName[de] = _('Google-Tasks-Indicator') +$GenericName[zh_CN] = _('Google-Tasks-Indicator') +$GenericName[fi] = _('Google-Tasks-Indicator') +$GenericName[ru] = _('Google-Tasks-Indicator') +$Name[ms] = _('Google-Taks-Indicator') +$Name[bs] = _('Google-Taks-Indicator') +$Name[pl] = _('Google-Taks-Indicator') +$Name[cs] = _('Google-Taks-Indicator') +$Name[pt_BR] = _('Google-Taks-Indicator') +$Name[ca] = _('Google-Taks-Indicator') +$Name[pt] = _('Google-Taks-Indicator') +$Comment[ms] = _('An indicator for Google Tasks') +$Comment[bs] = _('An indicator for Google Tasks') +$Comment[pl] = _('An indicator for Google Tasks') +$Comment[cs] = _('An indicator for Google Tasks') +$Comment[pt_BR] = _('An indicator for Google Tasks') +$Comment[ca] = _('An indicator for Google Tasks') +$Comment[pt] = _('An indicator for Google Tasks') +$GenericName[ms] = _('Google-Tasks-Indicator') +$GenericName[bs] = _('Google-Tasks-Indicator') +$GenericName[pl] = _('Google-Tasks-Indicator') +$GenericName[cs] = _('Google-Tasks-Indicator') +$GenericName[pt_BR] = _('Google-Tasks-Indicator') +$GenericName[ca] = _('Google-Tasks-Indicator') +$GenericName[pt] = _('Google-Tasks-Indicator') + diff -Nru google-tasks-indicator-0.0.3.2~quantal/bin/google-tasks-indicator google-tasks-indicator-0.0.5.1.quantal.1/bin/google-tasks-indicator --- google-tasks-indicator-0.0.3.2~quantal/bin/google-tasks-indicator 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/bin/google-tasks-indicator 2012-12-09 09:23:53.000000000 +0000 @@ -0,0 +1,47 @@ +#!/usr/bin/python3 +# -*- coding: UTF-8 -*- +# +# My-Weather-Indicator launcher +# +# Copyright (C) 2011 Lorenzo Carbonell Cerezo +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# +import os +import sys +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import Gtk +from gi.repository import Notify + +if __name__ == '__main__': + if __file__.startswith('/usr/bin'): + sys.path.insert(1, '/usr/share/google-tasks-indicator') + else: + sys.path.insert(1,os.path.normpath(os.path.join(os.getcwd(), '../src'))) + #################################################################### + import comun + from googletasksindicator import GoogleTasksIndicator + #################################################################### + print('Google-Tasks-Indicator version: %s'%comun.VERSION) + print('#####################################################') + Notify.init("google-tasks-indicator") + gti=GoogleTasksIndicator() + Gtk.main() + Gtk.main() +exit(0) + diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/Google-Tasks-Indicator.desktop google-tasks-indicator-0.0.5.1.quantal.1/data/Google-Tasks-Indicator.desktop --- google-tasks-indicator-0.0.3.2~quantal/data/Google-Tasks-Indicator.desktop 2012-03-03 21:20:16.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/Google-Tasks-Indicator.desktop 2013-01-19 06:20:24.000000000 +0000 @@ -1,12 +1,55 @@ - [Desktop Entry] -Name=Google-Tasks-Indicator -Version=0.0.1.0 -Exec=/usr/share/google-tasks-indicator/google-tasks-indicator.py -Comment=Google-Tasks-Indicator -Icon=/usr/share/pixmaps/google-tasks-indicator.svg -Type=Application -Terminal=false -StartupNotify=true -Encoding=UTF-8 -Categories=Utility; +Encoding = UTF-8 +Name = Google-Taks-Indicator +Version = 0.0.4.0 +Comment = An indicator for Google Tasks +GenericName = Google-Tasks-Indicator +Terminal = false +Icon = /usr/share/google-tasks-indicator/icons/google-tasks-indicator.svg +Type = Application +Exec = /usr/bin/google-tasks-indicator +Name[it] = Google-Taks-Indicator +Name[fr] = Google-Taks-Indicator +Name[es] = Google-Taks-Indicator +Name[ms] = Google-Taks-Indicator +Name[bs] = Google-Taks-Indicator +Name[tr] = Google-Taks-Indicator +Name[de] = Indikator für Google-Aufgaben +Name[zh_CN] = Google-Taks-Indicator +Name[pl] = Google-Taks-Indicator +Name[fi] = Google-Taks-Indicator +Name[cs] = Google-Taks-Indicator +Name[pt_BR] = Google-Taks-Indicator +Name[ca] = Google-Taks-Indicator +Name[ru] = Индикатор задачи Google +Name[pt] = Google-Taks-Indicator +Comment[it] = Un indicatore per Google Tasks +Comment[fr] = Un indicateur pour Google Tasks +Comment[es] = Un indicador para Google Tasks +Comment[ms] = Merupakan penunjuk untuk Google Tasks +Comment[bs] = Indikator za Google Tasks +Comment[tr] = Google Görevleri göstergesi +Comment[de] = Ein Indikator für Google-Aufgaben +Comment[zh_CN] = Google 任务提示器 +Comment[pl] = Aplet dla Google Tasks +Comment[fi] = Google Tasks -ilmaisin +Comment[cs] = Indikátor Google Tasks +Comment[pt_BR] = Um indicador para o Google Tasks +Comment[ca] = Un indicador per Google Tasks +Comment[ru] = Индикатор задач Google +Comment[pt] = Um indicador para o Google Tasks +GenericName[it] = Google-Tasks-Indicator +GenericName[fr] = Google-Tasks-Indicator +GenericName[es] = Google-Tasks-Indicator +GenericName[ms] = Google-Tasks-Indicator +GenericName[bs] = Google-Tasks-Indicator +GenericName[tr] = Google-Tasks-Indicator +GenericName[de] = Indikator für Google-Aufgaben +GenericName[zh_CN] = Google-Tasks-Indicator +GenericName[pl] = Google-Tasks-Indicator +GenericName[fi] = Google-Tasks-Indicator +GenericName[cs] = Google-Tasks-Indicator +GenericName[pt_BR] = Google-Tasks-Indicator +GenericName[ca] = Google-Tasks-Indicator +GenericName[ru] = Индикатор задач Google +GenericName[pt] = Google-Tasks-Indicator diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/google-tasks-indicator-autostart.desktop google-tasks-indicator-0.0.5.1.quantal.1/data/google-tasks-indicator-autostart.desktop --- google-tasks-indicator-0.0.3.2~quantal/data/google-tasks-indicator-autostart.desktop 2012-03-03 21:21:13.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/google-tasks-indicator-autostart.desktop 2012-12-07 18:15:08.000000000 +0000 @@ -1,7 +1,7 @@ [Desktop Entry] Type=Application -Exec=/usr/share/google-tasks-indicator/google-tasks-indicator.py +Exec=/usr/bin/google-tasks-indicator Hidden=false NoDisplay=false X-GNOME-Autostart-enabled=true diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/social/facebook.svg google-tasks-indicator-0.0.5.1.quantal.1/data/social/facebook.svg --- google-tasks-indicator-0.0.3.2~quantal/data/social/facebook.svg 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/social/facebook.svg 2012-09-30 07:20:18.000000000 +0000 @@ -0,0 +1,133 @@ + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/social/googleplus.svg google-tasks-indicator-0.0.5.1.quantal.1/data/social/googleplus.svg --- google-tasks-indicator-0.0.3.2~quantal/data/social/googleplus.svg 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/social/googleplus.svg 2012-12-01 06:37:18.000000000 +0000 @@ -0,0 +1,127 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/social/twitter.svg google-tasks-indicator-0.0.5.1.quantal.1/data/social/twitter.svg --- google-tasks-indicator-0.0.3.2~quantal/data/social/twitter.svg 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/social/twitter.svg 2012-09-30 07:25:18.000000000 +0000 @@ -0,0 +1,99 @@ + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + diff -Nru google-tasks-indicator-0.0.3.2~quantal/data/social/web.svg google-tasks-indicator-0.0.5.1.quantal.1/data/social/web.svg --- google-tasks-indicator-0.0.3.2~quantal/data/social/web.svg 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/data/social/web.svg 2012-09-30 07:38:09.000000000 +0000 @@ -0,0 +1,148 @@ + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + + + + + + + + + + + + diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/changelog google-tasks-indicator-0.0.5.1.quantal.1/debian/changelog --- google-tasks-indicator-0.0.3.2~quantal/debian/changelog 2012-11-06 21:31:53.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/changelog 2013-01-19 06:20:05.000000000 +0000 @@ -1,6 +1,57 @@ -google-tasks-indicator (0.0.3.2~quantal) quantal; urgency=low +google-tasks-indicator (0.0.5.1.quantal.1-1ubuntu1) quantal; urgency=low - -- Umair Riaz Tue, 06 Nov 2012 23:31:35 +0200 + * Added tasklist management + * Fixed bugs: + * #1093340 KeyError + * #1093343 Tasks are not uploading to Google Tasks + * #1097449 Typo: googletasksapi.py:215 should read "self.tasklists.keys()" in$ + * #1097450 Typo: show_tasks_dialog.py:143 should read "snd = TaskDialog(id)" + * #1097460 Typo: googletasksapi.py:378 should read params = {'tasklist':taskl$ + * #1097452 Selecting "All" Tasklists disables the ability to add a new task. + * Updated translations + + -- Lorenzo Carbonell Sat, 19 Jan 2013 07:19:28 +0100 + +google-tasks-indicator (0.0.5.0.quantal.3-1ubuntu1) quantal; urgency=low + + * Fixed bugs #953836 and #1093340 + + -- Lorenzo Carbonell Mon, 24 Dec 2012 10:33:12 +0100 + +google-tasks-indicator (0.0.5.0.quantal.1-1ubuntu1) quantal; urgency=low + + * Fixed some bugs + * Quantal version + + -- Lorenzo Carbonell Sun, 09 Dec 2012 10:51:32 +0100 + +google-tasks-indicator (0.0.5.0.precise.1-1ubuntu1) precise; urgency=low + + * Fixed some bugs with local work + + -- Lorenzo Carbonell Sun, 09 Dec 2012 10:21:17 +0100 + +google-tasks-indicator (0.0.4.2.precise.1-1ubuntu1) precise; urgency=low + + * Updated translations + + -- Lorenzo Carbonell Sat, 08 Dec 2012 09:23:27 +0100 + +google-tasks-indicator (0.0.4.1-1ubuntu1) precise; urgency=low + + * Using python 2.7 + + -- Lorenzo Carbonell Fri, 07 Dec 2012 19:26:05 +0100 + +google-tasks-indicator (0.0.4.0-1ubuntu1) precise; urgency=low + + * Local work + * Sync with Google + * Using requests + * Using OAuth2 + * Fixed several bugs + + -- Lorenzo Carbonell Fri, 07 Dec 2012 19:15:55 +0100 google-tasks-indicator (0.0.3.2-1ubuntu1) precise; urgency=low diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/control google-tasks-indicator-0.0.5.1.quantal.1/debian/control --- google-tasks-indicator-0.0.3.2~quantal/debian/control 2012-05-23 21:42:33.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/control 2012-12-09 09:53:03.000000000 +0000 @@ -1,17 +1,21 @@ Source: google-tasks-indicator Section: utils Priority: extra -Maintainer: Umair Riaz , Lorenzo Carbonell Cerezo -Build-Depends: debhelper (>= 7.0.50~), python-support, python (>=2.7) -Standards-Version: 3.8.3 -Homepage: http://www.NoobsLab.com , http://www.atareao.es +Maintainer: Lorenzo Carbonell Cerezo +Build-Depends: debhelper (>= 8), python, python-distutils-extra, python-polib +Standards-Version: 3.9.3 +Homepage: http://www.atareao.es Package: google-tasks-indicator Architecture: all Depends: ${misc:Depends}, ${python:Depends}, + python3, + python3-gi, gir1.2-gtk-3.0, gir1.2-gdkpixbuf-2.0, gir1.2-appindicator3-0.1, gir1.2-notify-0.7, - python-gflags + gir1.2-webkit-3.0, + python3-requests, + python3-dateutil Description: An indicator for Google Tasks diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/copyright google-tasks-indicator-0.0.5.1.quantal.1/debian/copyright --- google-tasks-indicator-0.0.3.2~quantal/debian/copyright 2012-05-23 21:42:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/copyright 2011-09-24 03:50:42.000000000 +0000 @@ -1,6 +1,3 @@ -This package was debianized by Umair Riaz - http://www.NoobsLab.com - - Format: http://dep.debian.net/deps/dep5 Upstream-Name: translate-me Source: http://www.atareao.es diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/google-tasks-indicator.install google-tasks-indicator-0.0.5.1.quantal.1/debian/google-tasks-indicator.install --- google-tasks-indicator-0.0.3.2~quantal/debian/google-tasks-indicator.install 2012-03-03 21:22:21.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/google-tasks-indicator.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,5 +0,0 @@ -src/* /usr/share/google-tasks-indicator -data/google-tasks-indicator-autostart.desktop /usr/share/google-tasks-indicator -data/Google-Tasks-Indicator.desktop /usr/share/applications -data/icons/*.svg /usr/share/google-tasks-indicator/icons -data/icons/google-tasks-indicator.svg /usr/share/pixmaps diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/pyversions google-tasks-indicator-0.0.5.1.quantal.1/debian/pyversions --- google-tasks-indicator-0.0.3.2~quantal/debian/pyversions 2011-09-24 03:50:54.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/pyversions 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -2.7- diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/rules google-tasks-indicator-0.0.5.1.quantal.1/debian/rules --- google-tasks-indicator-0.0.3.2~quantal/debian/rules 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/rules 2012-12-07 17:55:33.000000000 +0000 @@ -1,103 +1,6 @@ #!/usr/bin/make -f -# Sample debian/rules that uses debhelper. -# This file is public domain software, originally written by Joey Hess. -# -# This version is for packages that are architecture independent. +# -*- makefile -*- -# Uncomment this to turn on verbose mode. -#export DH_VERBOSE=1 -build: build-stamp -build-stamp: - dh_testdir - - # Add here commands to compile the package. - #$(MAKE) - - touch build-stamp - -clean: - dh_testdir - dh_testroot - rm -f build-stamp - - # Add here commands to clean up after the build process. - #$(MAKE) clean - #$(MAKE) distclean - - dh_clean - -install: build - dh_testdir - dh_testroot - dh_prep - dh_installdirs - dh_install - # Create languages directories - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/es/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack//LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/zh_CN/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/it/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/fi/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/tr/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/de/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/ru/LC_MESSAGES - mkdir -p ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/fr/LC_MESSAGES - # End create languages directories - # Compile languages - msgfmt template1/es.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/es/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack//LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/zh_CN.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/zh_CN/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/it.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/it/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/fi.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/fi/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/tr.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/tr/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/de.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/de/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/ru.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/ru/LC_MESSAGES/google-tasks-indicator.mo - msgfmt template1/fr.po -o ${CURDIR}/debian/google-tasks-indicator/usr/share/locale-langpack/fr/LC_MESSAGES/google-tasks-indicator.mo - # End comile languages - - # Add here commands to install the package into debian/. - #$(MAKE) prefix=`pwd`/debian/`dh_listpackages`/usr install - -# Build architecture-independent files here. -binary-indep: build install - dh_testdir - dh_testroot - dh_installchangelogs - dh_installdocs - dh_installexamples - # added gconf and icons - dh_gconf - dh_icons -# dh_installmenu -# dh_installdebconf -# dh_installlogrotate -# dh_installemacsen -# dh_installcatalogs -# dh_installpam -# dh_installmime -# dh_installinit -# dh_installcron -# dh_installinfo -# dh_installwm -# dh_installudev -# dh_lintian -# dh_bugfiles -# dh_undocumented - dh_installman - dh_link - dh_compress - dh_fixperms -# dh_perl - dh_pysupport - dh_installdeb - dh_gencontrol - dh_md5sums - dh_builddeb - -# Build architecture-dependent files here. -binary-arch: build install -# We have nothing to do by default. - -binary: binary-indep binary-arch -.PHONY: build clean binary-indep binary-arch binary install +%: + dh $@ --with python2 diff -Nru google-tasks-indicator-0.0.3.2~quantal/debian/source/format google-tasks-indicator-0.0.5.1.quantal.1/debian/source/format --- google-tasks-indicator-0.0.3.2~quantal/debian/source/format 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/debian/source/format 2013-04-23 11:49:59.716467109 +0000 @@ -0,0 +1 @@ +3.0 (native) diff -Nru google-tasks-indicator-0.0.3.2~quantal/msgfmt.py google-tasks-indicator-0.0.5.1.quantal.1/msgfmt.py --- google-tasks-indicator-0.0.3.2~quantal/msgfmt.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/msgfmt.py 2012-08-04 03:18:45.000000000 +0000 @@ -0,0 +1,219 @@ +# -*- coding: utf-8 -*- +# Written by Martin v. Lwis +# Plural forms support added by alexander smishlajev +""" +Generate binary message catalog from textual translation description. + +This program converts a textual Uniforum-style message catalog (.po file) into +a binary GNU catalog (.mo file). This is essentially the same function as the +GNU msgfmt program, however, it is a simpler implementation. + +Usage: msgfmt.py [OPTIONS] filename.po + +Options: + -o file + --output-file=file + Specify the output file to write to. If omitted, output will go to a + file named filename.mo (based off the input file name). + + -h + --help + Print this message and exit. + + -V + --version + Display version information and exit. +""" + +import sys +import os +import getopt +import struct +import array + +__version__ = "1.1" + +MESSAGES = {} + + +def usage (ecode, msg=''): + """ + Print usage and msg and exit with given code. + """ + print >> sys.stderr, __doc__ + if msg: + print >> sys.stderr, msg + sys.exit(ecode) + + +def add (msgid, transtr, fuzzy): + """ + Add a non-fuzzy translation to the dictionary. + """ + global MESSAGES + if not fuzzy and transtr and not transtr.startswith('\0'): + MESSAGES[msgid] = transtr + + +def generate (): + """ + Return the generated output. + """ + global MESSAGES + keys = MESSAGES.keys() + # the keys are sorted in the .mo file + keys.sort() + offsets = [] + ids = strs = '' + for _id in keys: + # For each string, we need size and file offset. Each string is NUL + # terminated; the NUL does not count into the size. + offsets.append((len(ids), len(_id), len(strs), len(MESSAGES[_id]))) + ids += _id + '\0' + strs += MESSAGES[_id] + '\0' + output = '' + # The header is 7 32-bit unsigned integers. We don't use hash tables, so + # the keys start right after the index tables. + # translated string. + keystart = 7*4+16*len(keys) + # and the values start after the keys + valuestart = keystart + len(ids) + koffsets = [] + voffsets = [] + # The string table first has the list of keys, then the list of values. + # Each entry has first the size of the string, then the file offset. + for o1, l1, o2, l2 in offsets: + koffsets += [l1, o1+keystart] + voffsets += [l2, o2+valuestart] + offsets = koffsets + voffsets + output = struct.pack("Iiiiiii", + 0x950412deL, # Magic + 0, # Version + len(keys), # # of entries + 7*4, # start of key index + 7*4+len(keys)*8, # start of value index + 0, 0) # size and offset of hash table + output += array.array("i", offsets).tostring() + output += ids + output += strs + return output + + +def make (filename, outfile): + ID = 1 + STR = 2 + global MESSAGES + MESSAGES = {} + + # Compute .mo name from .po name and arguments + if filename.endswith('.po'): + infile = filename + else: + infile = filename + '.po' + if outfile is None: + outfile = os.path.splitext(infile)[0] + '.mo' + + try: + lines = open(infile).readlines() + except IOError, msg: + print >> sys.stderr, msg + sys.exit(1) + + section = None + fuzzy = 0 + + # Parse the catalog + msgid = msgstr = '' + lno = 0 + for l in lines: + lno += 1 + # If we get a comment line after a msgstr, this is a new entry + if l[0] == '#' and section == STR: + add(msgid, msgstr, fuzzy) + section = None + fuzzy = 0 + # Record a fuzzy mark + if l[:2] == '#,' and (l.find('fuzzy') >= 0): + fuzzy = 1 + # Skip comments + if l[0] == '#': + continue + # Start of msgid_plural section, separate from singular form with \0 + if l.startswith('msgid_plural'): + msgid += '\0' + l = l[12:] + # Now we are in a msgid section, output previous section + elif l.startswith('msgid'): + if section == STR: + add(msgid, msgstr, fuzzy) + section = ID + l = l[5:] + msgid = msgstr = '' + # Now we are in a msgstr section + elif l.startswith('msgstr'): + section = STR + l = l[6:] + # Check for plural forms + if l.startswith('['): + # Separate plural forms with \0 + if not l.startswith('[0]'): + msgstr += '\0' + # Ignore the index - must come in sequence + l = l[l.index(']') + 1:] + # Skip empty lines + l = l.strip() + if not l: + continue + # XXX: Does this always follow Python escape semantics? + l = eval(l) + if section == ID: + msgid += l + elif section == STR: + msgstr += l + else: + print >> sys.stderr, 'Syntax error on %s:%d' % (infile, lno), \ + 'before:' + print >> sys.stderr, l + sys.exit(1) + # Add last entry + if section == STR: + add(msgid, msgstr, fuzzy) + + # Compute output + output = generate() + + try: + open(outfile,"wb").write(output) + except IOError,msg: + print >> sys.stderr, msg + + +def main (): + try: + opts, args = getopt.getopt(sys.argv[1:], 'hVo:', + ['help', 'version', 'output-file=']) + except getopt.error, msg: + usage(1, msg) + + outfile = None + # parse options + for opt, arg in opts: + if opt in ('-h', '--help'): + usage(0) + elif opt in ('-V', '--version'): + print >> sys.stderr, "msgfmt.py", __version__ + sys.exit(0) + elif opt in ('-o', '--output-file'): + outfile = arg + # do it + if not args: + print >> sys.stderr, 'No input file given' + print >> sys.stderr, "Try `msgfmt --help' for more information." + return + + for filename in args: + make(filename, outfile) + + +if __name__ == '__main__': + main() diff -Nru google-tasks-indicator-0.0.3.2~quantal/setup.py google-tasks-indicator-0.0.5.1.quantal.1/setup.py --- google-tasks-indicator-0.0.3.2~quantal/setup.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/setup.py 2013-01-19 06:21:49.000000000 +0000 @@ -0,0 +1,351 @@ +#!/usr/bin/env python +# +''' +from distutils.core import setup +''' +from distutils.core import setup +from DistUtilsExtra.command import * +from distutils import cmd +from distutils.command.install_data import install_data as _install_data +from distutils.command.build import build as _build + +import msgfmt +import os +import glob +import shlex +import subprocess +import shutil +import polib +import ConfigParser +import codecs + +DATA_FILES = [ +('/usr/share/google-tasks-indicator',glob.glob('src/*.py')), +('/usr/bin', ['bin/google-tasks-indicator']), +('/usr/share/applications', ['data/Google-Tasks-Indicator.desktop']), +('/usr/share/google-tasks-indicator', ['data/google-tasks-indicator-autostart.desktop']), +('/usr/share/google-tasks-indicator/icons', glob.glob('data/icons/*.svg')), +('/usr/share/google-tasks-indicator/social', glob.glob('data/social/*.svg')) +] + +MAIN_DIR = os.getcwd() +DATA_DIR = os.path.join(MAIN_DIR,'data') +DEBIAN_DIR = os.path.join(MAIN_DIR,'debian') +LANGUAGES_DIR = os.path.join(MAIN_DIR,'template1') +SRC_DIR = os.path.join(MAIN_DIR,'src') +TEMPLATE = os.path.join(LANGUAGES_DIR,'template1.pot') +CHANGELOG = os.path.join(DEBIAN_DIR,'changelog') +f = open(CHANGELOG,'r') +line = f.readline() +f.close() +pos=line.find('(') +posf=line.find('-',pos) +APP = line[:pos].strip().lower() +VERSION = line[pos+1:posf].strip() +APPNAME = APP.title() +AUTHOR = 'Lorenzo Carbonell' +AUTHOR_EMAIL = 'lorenzo.carbonell.cerezo@gmail.com' +URL = 'http://www.atareao.es' +LICENSE = 'GNU General Public License (GPL)' +COMPILED_LANGUAGE_FILE = '%s.mo'%APP + +def get_entry(filein,msgid): + try: + po = polib.pofile(filein) + print po.metadata['Content-Type'] + for entry in po: + if entry.msgid == msgid: + return entry.msgstr + except Exception,e: + print filein, e + pass + return None + +######################################################################## +def ejecuta(comando): + print ('Ejecutando... %s'%comando) + args = shlex.split(comando) + p = subprocess.Popen(args, bufsize=10000, stdout=subprocess.PIPE) + valor = p.communicate()[0] + return valor +######################################################################## +def list_src(): + file_txt = os.path.join(MAIN_DIR,'files.txt') + f = open(file_txt,'w') + for file in glob.glob(os.path.join(SRC_DIR,'*.py')): + f.write('%s\n'%file) + for file in glob.glob(os.path.join(MAIN_DIR,'*.desktop.in')): + f.write('%s\n'%file) + f.close() + return file_txt + +def list_languages(): + lans = [] + file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') + if os.path.exists(file_txt)==True: + f = open(file_txt,'r') + for linea in f.readlines(): + lan = linea[:-1] + print lan + lans.append(lan) + f.close() + for file in glob.glob(os.path.join(LANGUAGES_DIR,'*.po')): + lan = os.path.splitext(os.path.basename(file))[0] + if lan not in lans: + lans.append(lan) + f = open(file_txt,'w') + for lan in lans: + f.write('%s\n'%lan) + f.close() + return file_txt + +def update_translations(): + file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') + f = open(file_txt,'r') + for file in f.readlines(): + lan = file[:-1] + file = os.path.join(LANGUAGES_DIR,lan+'.po') + print '############################################################' + print lan + print '############################################################' + if os.path.exists(file): + command = 'msgmerge -U %s %s'%(file,TEMPLATE) + else: + command = 'msginit --output-file=%s --input=%s --locale=%s'%(file,TEMPLATE,lan) + print ejecuta(command) + edit_language_file(file) + f.close() + +def edit_language_file(file): + po = polib.pofile(file) + lang = file.split('/')[-1:][0].split('.')[0] + po.metadata['Project-Id-Version'] = '%s %s'%(APP,VERSION) + po.metadata['Report-Msgid-Bugs-To'] = AUTHOR_EMAIL + po.metadata['Language'] = lang + po.metadata['Content-Type'] = 'text/plain; charset=UTF-8' + po.metadata['Content-Transfer-Encoding'] = '8bit' + po.save() + +def update_desktop_file_fp(): + lns = [] + for filein in glob.glob('./template1/*.po'): + ln = os.path.splitext(os.path.split(filein)[1])[0] + lns.append(ln) + for filedesktopin in glob.glob('*.desktop.in'): + desktopfile = ConfigParser.ConfigParser() + desktopfile.optionxform = str + desktopfile.readfp(codecs.open(filedesktopin,encoding = 'utf-8',mode='r')) + if len(lns)>0: + for entry in desktopfile.items('Desktop Entry'): + if entry[0].startswith('_'): + for ln in lns: + desktopfile.set('Desktop Entry','$%s[%s]'%(entry[0][1:],ln),"_('%s')"%entry[1]) + with codecs.open(filedesktopin,encoding = 'utf-8',mode='w') as outputfile: + desktopfile.write(outputfile) + + +def update_desktop_file(): + lns = [] + for filein in glob.glob('./template1/*.po'): + ln = os.path.splitext(os.path.split(filein)[1])[0] + lns.append(ln) + for filedesktopin in glob.glob('*.desktop.in'): + desktopfilename = os.path.splitext(os.path.split(filedesktopin)[1])[0] + print desktopfilename + fileout = os.path.join(DATA_DIR,desktopfilename) + print fileout + if os.path.exists(fileout): + os.remove(fileout) + fileout = codecs.open('./data/%s'%desktopfilename,encoding = 'utf-8',mode='w') + fileout.write('[Desktop Entry]\n') + # + desktopfile = ConfigParser.ConfigParser() + desktopfile.optionxform = str + desktopfile.readfp(codecs.open('./%s.in'%desktopfilename,encoding = 'utf-8',mode='r')) + if len(lns)>0: + for entry in desktopfile.items('Desktop Entry'): + if not entry[0].startswith('$'): + if entry[0].startswith('_'): + fileout.write('%s = %s\n'%(entry[0][1:],entry[1])) + else: + fileout.write('%s = %s\n'%(entry[0],entry[1])) + for entry in desktopfile.items('Desktop Entry'): + if entry[0].startswith('_') and not entry[0].startswith('$'): + for ln in lns: + filepo = os.path.join(LANGUAGES_DIR,'%s.po'%ln) + msgstr = get_entry(filepo,entry[1]) + print filepo + if not msgstr or msgstr == '': + msgstr = entry[1] + + print '%s[%s]=%s'%(entry[0][1:],ln,msgstr) + fileout.write('%s[%s] = %s\n'%(entry[0][1:],ln,msgstr)) + fileout.close() + +def remove_security_copies(): + for file in glob.glob(os.path.join(LANGUAGES_DIR,'*.po~')): + os.remove(file) + +def delete_it(file): + if os.path.exists(file): + if os.path.isdir(file): + shutil.rmtree(file) + else: + os.remove(file) + +def remove_files(dir,ext): + files = [] + for file in glob.glob(os.path.join(dir,'*')): + if file != None and os.path.exists(file): + if file and os.path.isdir(file): + morefiles = remove_files(file,ext) + if morefiles: + files.extend(morefiles) + else: + files.append(file) + for file in files: + if os.path.splitext(file)[1] == ext: + os.remove(file) + +def remove_compiled_files(dir): + remove_files(dir,'.pyc') + +def remove_languages_saved_files(dir): + remove_files(dir,'.po~') + +def babilon(): + print '############################################################' + print 'Parent dir -> %s'%MAIN_DIR + print 'Languages dir -> %s'%LANGUAGES_DIR + print 'Source dir -> %s'%SRC_DIR + print '############################################################' + print 'Updating Desktop File First Part' + print '############################################################' + update_desktop_file_fp() + print '############################################################' + print 'Updating template' + print '############################################################' + files_file = list_src() + command = 'xgettext --msgid-bugs-address=%s --language=Python --keyword=_ --keyword=N_ --output=%s --files-from=%s'%(AUTHOR_EMAIL,TEMPLATE,files_file) + print ejecuta(command) + delete_it(files_file) + print '############################################################' + print 'List languages' + print '############################################################' + # + list_languages() + # + print '############################################################' + print 'Updating translations' + print '############################################################' + update_translations() + print '############################################################' + print 'Updating Desktop File' + print '############################################################' + update_desktop_file() + print '############################################################' + print 'Removing security copies' + print '############################################################' + remove_security_copies() + + +class clean_and_compile(cmd.Command): + description = 'Clean and compile languages' + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + remove_compiled_files(SRC_DIR) + babilon() + +class translate(build_extra.build_extra): + sub_commands = build_extra.build_extra.sub_commands + [('clean_and_compile', None)] + def run(self): + build_extra.build_extra.run(self) + pass + + +class build_trans(cmd.Command): + description = 'Compile .po files into .mo files' + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + po_dir = os.path.join(os.path.dirname(os.curdir), 'template1') + for path, names, filenames in os.walk(po_dir): + for f in filenames: + if f.endswith('.po'): + lang = f[:len(f) - 3] + src = os.path.join(path, f) + dest_path = os.path.join('build', 'locale-langpack', lang, 'LC_MESSAGES') + dest = os.path.join(dest_path, COMPILED_LANGUAGE_FILE) + print('###########################################') + print('###########################################') + print('File: %s'%f) + print('Language: %s'%lang) + print(dest_path) + print(dest) + print('###########################################') + print('###########################################') + if not os.path.exists(dest_path): + os.makedirs(dest_path) + if not os.path.exists(dest): + print 'Compiling %s' % src + msgfmt.make(src, dest) + else: + src_mtime = os.stat(src)[8] + dest_mtime = os.stat(dest)[8] + if src_mtime > dest_mtime: + print 'Compiling %s' % src + msgfmt.make(src, dest) + +class build(build_extra.build_extra): + sub_commands = build_extra.build_extra.sub_commands + [('build_trans', None)] + def run(self): + build_extra.build_extra.run(self) + +class install_data(_install_data): + def run(self): + for lang in os.listdir('build/locale-langpack/'): + lang_dir = os.path.join('share', 'locale-langpack', lang, 'LC_MESSAGES') + lang_file = os.path.join('build', 'locale-langpack', lang, 'LC_MESSAGES', COMPILED_LANGUAGE_FILE) + self.data_files.append( (lang_dir, [lang_file]) ) + _install_data.run(self) + +class command_create_deb(cmd.Command): + description = 'Create deb package' + def initialize_options(self): + pass + + def finalize_options(self): + pass + + def run(self): + print(ejecuta('debuild -us -uc')) + +class create_deb(build_extra.build_extra): + sub_commands = build_extra.build_extra.sub_commands + [('command_create_deb', None)] + def run(self): + build_extra.build_extra.run(self) + pass + +setup(name=APP, + version=VERSION, + author=AUTHOR, + author_email=AUTHOR_EMAIL, + url=URL, + license=LICENSE, + data_files=DATA_FILES, + cmdclass={'build': build, + 'translate':translate, + 'clean_and_compile':clean_and_compile, + 'command_create_deb':command_create_deb, + 'build_trans': build_trans, + 'create_deb':create_deb, + 'install_data': install_data,}) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/__init__.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/__init__.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/contrib/latitude/future.json google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/contrib/latitude/future.json --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/contrib/latitude/future.json 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/contrib/latitude/future.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,81 +0,0 @@ -{ - "baseUrl": "https://www.googleapis.com/", - "auth": { - "request": { - "url": "https://www.google.com/accounts/OAuthGetRequestToken", - "parameters": { - "xoauth_displayname": { - "parameterType": "query", - "required": false - }, - "domain": { - "parameterType": "query", - "required": true - }, - "scope": { - "parameterType": "query", - "required": true - } - } - }, - "authorize": { - "url": "https://www.google.com/latitude/apps/OAuthAuthorizeToken", - "parameters": { - "oauth_token": { - "parameterType": "query", - "required": true - }, - "iconUrl": { - "parameterType": "query", - "required": false - }, - "domain": { - "parameterType": "query", - "required": true - }, - "scope": { - "parameterType": "query", - "required": true - }, - "location": { - "parameterType": "query", - "required": false - }, - "granularity": { - "parameterType": "query", - "required": false - } - } - }, - "access": { - "url": "https://www.google.com/accounts/OAuthGetAccessToken", - "parameters": { - "domain": { - "parameterType": "query", - "required": true - }, - "scope": { - "parameterType": "query", - "required": true - } - } - } - }, - "resources": { - "currentLocation": { - "methods": { - "delete": {}, - "get": {}, - "insert": {} - } - }, - "location": { - "methods": { - "delete": {}, - "get": {}, - "insert": {}, - "list": {} - } - } - } -} diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/contrib/moderator/future.json google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/contrib/moderator/future.json --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/contrib/moderator/future.json 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/contrib/moderator/future.json 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -{ - "baseUrl": "https://www.googleapis.com/", - "auth": { - "request": { - "url": "https://www.google.com/accounts/OAuthGetRequestToken", - "parameters": { - "xoauth_displayname": { - "parameterType": "query", - "required": false - }, - "domain": { - "parameterType": "query", - "required": false - }, - "scope": { - "parameterType": "query", - "required": true - } - } - }, - "authorize": { - "url": "https://www.google.com/accounts/OAuthAuthorizeToken", - "parameters": { - "oauth_token": { - "parameterType": "query", - "required": true - }, - "iconUrl": { - "parameterType": "query", - "required": false - }, - "domain": { - "parameterType": "query", - "required": false - }, - "scope": { - "parameterType": "query", - "required": true - } - } - }, - "access": { - "url": "https://www.google.com/accounts/OAuthGetAccessToken", - "parameters": { - "domain": { - "parameterType": "query", - "required": false - }, - "scope": { - "parameterType": "query", - "required": true - } - } - } - }, - "resources": { - "profiles": { - "methods": { - "get": {}, - "update": {} - } - }, - "responses": { - "methods": { - "insert": {}, - "list": {} - } - }, - "series": { - "methods": { - "get": {}, - "insert": {}, - "list": {}, - "update": {} - } - }, - "submissions": { - "methods": { - "get": {}, - "insert": {}, - "list": {} - } - }, - "tags": { - "methods": { - "delete": {}, - "insert": {}, - "list": {} - } - }, - "topics": { - "methods": { - "get": {}, - "insert": {}, - "list": {} - } - }, - "votes": { - "methods": { - "get": {}, - "insert": {}, - "list": {}, - "update": {} - } - } - } -} diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/discovery.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/discovery.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/discovery.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/discovery.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,727 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Client for discovery based APIs - -A client library for Google's discovery based APIs. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' -__all__ = [ - 'build', 'build_from_document' - ] - -import copy -import httplib2 -import logging -import os -import random -import re -import uritemplate -import urllib -import urlparse -import mimeparse -import mimetypes - -try: - from urlparse import parse_qsl -except ImportError: - from cgi import parse_qsl - -from apiclient.errors import HttpError -from apiclient.errors import InvalidJsonError -from apiclient.errors import MediaUploadSizeError -from apiclient.errors import UnacceptableMimeTypeError -from apiclient.errors import UnknownApiNameOrVersion -from apiclient.errors import UnknownLinkType -from apiclient.http import HttpRequest -from apiclient.http import MediaFileUpload -from apiclient.http import MediaUpload -from apiclient.model import JsonModel -from apiclient.model import RawModel -from apiclient.schema import Schemas -from email.mime.multipart import MIMEMultipart -from email.mime.nonmultipart import MIMENonMultipart -from oauth2client.anyjson import simplejson - - -URITEMPLATE = re.compile('{[^}]*}') -VARNAME = re.compile('[a-zA-Z0-9_-]+') -DISCOVERY_URI = ('https://www.googleapis.com/discovery/v1/apis/' - '{api}/{apiVersion}/rest') -DEFAULT_METHOD_DOC = 'A description of how to use this function' - -# Query parameters that work, but don't appear in discovery -STACK_QUERY_PARAMETERS = ['trace', 'fields', 'pp', 'prettyPrint', 'userIp', - 'userip', 'strict'] - -RESERVED_WORDS = ['and', 'assert', 'break', 'class', 'continue', 'def', 'del', - 'elif', 'else', 'except', 'exec', 'finally', 'for', 'from', - 'global', 'if', 'import', 'in', 'is', 'lambda', 'not', 'or', - 'pass', 'print', 'raise', 'return', 'try', 'while' ] - - -def _fix_method_name(name): - if name in RESERVED_WORDS: - return name + '_' - else: - return name - - -def _write_headers(self): - # Utility no-op method for multipart media handling - pass - - -def _add_query_parameter(url, name, value): - """Adds a query parameter to a url. - - Replaces the current value if it already exists in the URL. - - Args: - url: string, url to add the query parameter to. - name: string, query parameter name. - value: string, query parameter value. - - Returns: - Updated query parameter. Does not update the url if value is None. - """ - if value is None: - return url - else: - parsed = list(urlparse.urlparse(url)) - q = dict(parse_qsl(parsed[4])) - q[name] = value - parsed[4] = urllib.urlencode(q) - return urlparse.urlunparse(parsed) - - -def key2param(key): - """Converts key names into parameter names. - - For example, converting "max-results" -> "max_results" - """ - result = [] - key = list(key) - if not key[0].isalpha(): - result.append('x') - for c in key: - if c.isalnum(): - result.append(c) - else: - result.append('_') - - return ''.join(result) - - -def build(serviceName, - version, - http=None, - discoveryServiceUrl=DISCOVERY_URI, - developerKey=None, - model=None, - requestBuilder=HttpRequest): - """Construct a Resource for interacting with an API. - - Construct a Resource object for interacting with - an API. The serviceName and version are the - names from the Discovery service. - - Args: - serviceName: string, name of the service - version: string, the version of the service - http: httplib2.Http, An instance of httplib2.Http or something that acts - like it that HTTP requests will be made through. - discoveryServiceUrl: string, a URI Template that points to - the location of the discovery service. It should have two - parameters {api} and {apiVersion} that when filled in - produce an absolute URI to the discovery document for - that service. - developerKey: string, key obtained - from https://code.google.com/apis/console - model: apiclient.Model, converts to and from the wire format - requestBuilder: apiclient.http.HttpRequest, encapsulator for - an HTTP request - - Returns: - A Resource object with methods for interacting with - the service. - """ - params = { - 'api': serviceName, - 'apiVersion': version - } - - if http is None: - http = httplib2.Http() - - requested_url = uritemplate.expand(discoveryServiceUrl, params) - - # REMOTE_ADDR is defined by the CGI spec [RFC3875] as the environment - # variable that contains the network address of the client sending the - # request. If it exists then add that to the request for the discovery - # document to avoid exceeding the quota on discovery requests. - if 'REMOTE_ADDR' in os.environ: - requested_url = _add_query_parameter(requested_url, 'userIp', - os.environ['REMOTE_ADDR']) - logging.info('URL being requested: %s' % requested_url) - - resp, content = http.request(requested_url) - - if resp.status == 404: - raise UnknownApiNameOrVersion("name: %s version: %s" % (serviceName, - version)) - if resp.status >= 400: - raise HttpError(resp, content, requested_url) - - try: - service = simplejson.loads(content) - except ValueError, e: - logging.error('Failed to parse as JSON: ' + content) - raise InvalidJsonError() - - filename = os.path.join(os.path.dirname(__file__), 'contrib', - serviceName, 'future.json') - try: - f = file(filename, 'r') - future = f.read() - f.close() - except IOError: - future = None - - return build_from_document(content, discoveryServiceUrl, future, - http, developerKey, model, requestBuilder) - - -def build_from_document( - service, - base, - future=None, - http=None, - developerKey=None, - model=None, - requestBuilder=HttpRequest): - """Create a Resource for interacting with an API. - - Same as `build()`, but constructs the Resource object - from a discovery document that is it given, as opposed to - retrieving one over HTTP. - - Args: - service: string, discovery document - base: string, base URI for all HTTP requests, usually the discovery URI - future: string, discovery document with future capabilities - auth_discovery: dict, information about the authentication the API supports - http: httplib2.Http, An instance of httplib2.Http or something that acts - like it that HTTP requests will be made through. - developerKey: string, Key for controlling API usage, generated - from the API Console. - model: Model class instance that serializes and - de-serializes requests and responses. - requestBuilder: Takes an http request and packages it up to be executed. - - Returns: - A Resource object with methods for interacting with - the service. - """ - - service = simplejson.loads(service) - base = urlparse.urljoin(base, service['basePath']) - if future: - future = simplejson.loads(future) - auth_discovery = future.get('auth', {}) - else: - future = {} - auth_discovery = {} - schema = Schemas(service) - - if model is None: - features = service.get('features', []) - model = JsonModel('dataWrapper' in features) - resource = createResource(http, base, model, requestBuilder, developerKey, - service, future, schema) - - def auth_method(): - """Discovery information about the authentication the API uses.""" - return auth_discovery - - setattr(resource, 'auth_discovery', auth_method) - - return resource - - -def _cast(value, schema_type): - """Convert value to a string based on JSON Schema type. - - See http://tools.ietf.org/html/draft-zyp-json-schema-03 for more details on - JSON Schema. - - Args: - value: any, the value to convert - schema_type: string, the type that value should be interpreted as - - Returns: - A string representation of 'value' based on the schema_type. - """ - if schema_type == 'string': - if type(value) == type('') or type(value) == type(u''): - return value - else: - return str(value) - elif schema_type == 'integer': - return str(int(value)) - elif schema_type == 'number': - return str(float(value)) - elif schema_type == 'boolean': - return str(bool(value)).lower() - else: - if type(value) == type('') or type(value) == type(u''): - return value - else: - return str(value) - -MULTIPLIERS = { - "KB": 2 ** 10, - "MB": 2 ** 20, - "GB": 2 ** 30, - "TB": 2 ** 40, - } - - -def _media_size_to_long(maxSize): - """Convert a string media size, such as 10GB or 3TB into an integer.""" - if len(maxSize) < 2: - return 0 - units = maxSize[-2:].upper() - multiplier = MULTIPLIERS.get(units, 0) - if multiplier: - return int(maxSize[:-2]) * multiplier - else: - return int(maxSize) - - -def createResource(http, baseUrl, model, requestBuilder, - developerKey, resourceDesc, futureDesc, schema): - - class Resource(object): - """A class for interacting with a resource.""" - - def __init__(self): - self._http = http - self._baseUrl = baseUrl - self._model = model - self._developerKey = developerKey - self._requestBuilder = requestBuilder - - def createMethod(theclass, methodName, methodDesc, futureDesc): - methodName = _fix_method_name(methodName) - pathUrl = methodDesc['path'] - httpMethod = methodDesc['httpMethod'] - methodId = methodDesc['id'] - - mediaPathUrl = None - accept = [] - maxSize = 0 - if 'mediaUpload' in methodDesc: - mediaUpload = methodDesc['mediaUpload'] - # TODO(jcgregorio) Use URLs from discovery once it is updated. - parsed = list(urlparse.urlparse(baseUrl)) - basePath = parsed[2] - mediaPathUrl = '/upload' + basePath + pathUrl - accept = mediaUpload['accept'] - maxSize = _media_size_to_long(mediaUpload.get('maxSize', '')) - - if 'parameters' not in methodDesc: - methodDesc['parameters'] = {} - for name in STACK_QUERY_PARAMETERS: - methodDesc['parameters'][name] = { - 'type': 'string', - 'location': 'query' - } - - if httpMethod in ['PUT', 'POST', 'PATCH'] and 'request' in methodDesc: - methodDesc['parameters']['body'] = { - 'description': 'The request body.', - 'type': 'object', - 'required': True, - } - if 'request' in methodDesc: - methodDesc['parameters']['body'].update(methodDesc['request']) - else: - methodDesc['parameters']['body']['type'] = 'object' - if 'mediaUpload' in methodDesc: - methodDesc['parameters']['media_body'] = { - 'description': 'The filename of the media request body.', - 'type': 'string', - 'required': False, - } - if 'body' in methodDesc['parameters']: - methodDesc['parameters']['body']['required'] = False - - argmap = {} # Map from method parameter name to query parameter name - required_params = [] # Required parameters - repeated_params = [] # Repeated parameters - pattern_params = {} # Parameters that must match a regex - query_params = [] # Parameters that will be used in the query string - path_params = {} # Parameters that will be used in the base URL - param_type = {} # The type of the parameter - enum_params = {} # Allowable enumeration values for each parameter - - - if 'parameters' in methodDesc: - for arg, desc in methodDesc['parameters'].iteritems(): - param = key2param(arg) - argmap[param] = arg - - if desc.get('pattern', ''): - pattern_params[param] = desc['pattern'] - if desc.get('enum', ''): - enum_params[param] = desc['enum'] - if desc.get('required', False): - required_params.append(param) - if desc.get('repeated', False): - repeated_params.append(param) - if desc.get('location') == 'query': - query_params.append(param) - if desc.get('location') == 'path': - path_params[param] = param - param_type[param] = desc.get('type', 'string') - - for match in URITEMPLATE.finditer(pathUrl): - for namematch in VARNAME.finditer(match.group(0)): - name = key2param(namematch.group(0)) - path_params[name] = name - if name in query_params: - query_params.remove(name) - - def method(self, **kwargs): - for name in kwargs.iterkeys(): - if name not in argmap: - raise TypeError('Got an unexpected keyword argument "%s"' % name) - - for name in required_params: - if name not in kwargs: - raise TypeError('Missing required parameter "%s"' % name) - - for name, regex in pattern_params.iteritems(): - if name in kwargs: - if isinstance(kwargs[name], basestring): - pvalues = [kwargs[name]] - else: - pvalues = kwargs[name] - for pvalue in pvalues: - if re.match(regex, pvalue) is None: - raise TypeError( - 'Parameter "%s" value "%s" does not match the pattern "%s"' % - (name, pvalue, regex)) - - for name, enums in enum_params.iteritems(): - if name in kwargs: - # We need to handle the case of a repeated enum - # name differently, since we want to handle both - # arg='value' and arg=['value1', 'value2'] - if (name in repeated_params and - not isinstance(kwargs[name], basestring)): - values = kwargs[name] - else: - values = [kwargs[name]] - for value in values: - if value not in enums: - raise TypeError( - 'Parameter "%s" value "%s" is not an allowed value in "%s"' % - (name, value, str(enums))) - - actual_query_params = {} - actual_path_params = {} - for key, value in kwargs.iteritems(): - to_type = param_type.get(key, 'string') - # For repeated parameters we cast each member of the list. - if key in repeated_params and type(value) == type([]): - cast_value = [_cast(x, to_type) for x in value] - else: - cast_value = _cast(value, to_type) - if key in query_params: - actual_query_params[argmap[key]] = cast_value - if key in path_params: - actual_path_params[argmap[key]] = cast_value - body_value = kwargs.get('body', None) - media_filename = kwargs.get('media_body', None) - - if self._developerKey: - actual_query_params['key'] = self._developerKey - - model = self._model - # If there is no schema for the response then presume a binary blob. - if 'response' not in methodDesc: - model = RawModel() - - headers = {} - headers, params, query, body = model.request(headers, - actual_path_params, actual_query_params, body_value) - - expanded_url = uritemplate.expand(pathUrl, params) - url = urlparse.urljoin(self._baseUrl, expanded_url + query) - - resumable = None - multipart_boundary = '' - - if media_filename: - # Ensure we end up with a valid MediaUpload object. - if isinstance(media_filename, basestring): - (media_mime_type, encoding) = mimetypes.guess_type(media_filename) - if media_mime_type is None: - raise UnknownFileType(media_filename) - if not mimeparse.best_match([media_mime_type], ','.join(accept)): - raise UnacceptableMimeTypeError(media_mime_type) - media_upload = MediaFileUpload(media_filename, media_mime_type) - elif isinstance(media_filename, MediaUpload): - media_upload = media_filename - else: - raise TypeError('media_filename must be str or MediaUpload.') - - # Check the maxSize - if maxSize > 0 and media_upload.size() > maxSize: - raise MediaUploadSizeError("Media larger than: %s" % maxSize) - - # Use the media path uri for media uploads - expanded_url = uritemplate.expand(mediaPathUrl, params) - url = urlparse.urljoin(self._baseUrl, expanded_url + query) - if media_upload.resumable(): - url = _add_query_parameter(url, 'uploadType', 'resumable') - - if media_upload.resumable(): - # This is all we need to do for resumable, if the body exists it gets - # sent in the first request, otherwise an empty body is sent. - resumable = media_upload - else: - # A non-resumable upload - if body is None: - # This is a simple media upload - headers['content-type'] = media_upload.mimetype() - body = media_upload.getbytes(0, media_upload.size()) - url = _add_query_parameter(url, 'uploadType', 'media') - else: - # This is a multipart/related upload. - msgRoot = MIMEMultipart('related') - # msgRoot should not write out it's own headers - setattr(msgRoot, '_write_headers', lambda self: None) - - # attach the body as one part - msg = MIMENonMultipart(*headers['content-type'].split('/')) - msg.set_payload(body) - msgRoot.attach(msg) - - # attach the media as the second part - msg = MIMENonMultipart(*media_upload.mimetype().split('/')) - msg['Content-Transfer-Encoding'] = 'binary' - - payload = media_upload.getbytes(0, media_upload.size()) - msg.set_payload(payload) - msgRoot.attach(msg) - body = msgRoot.as_string() - - multipart_boundary = msgRoot.get_boundary() - headers['content-type'] = ('multipart/related; ' - 'boundary="%s"') % multipart_boundary - url = _add_query_parameter(url, 'uploadType', 'multipart') - - logging.info('URL being requested: %s' % url) - return self._requestBuilder(self._http, - model.response, - url, - method=httpMethod, - body=body, - headers=headers, - methodId=methodId, - resumable=resumable) - - docs = [methodDesc.get('description', DEFAULT_METHOD_DOC), '\n\n'] - if len(argmap) > 0: - docs.append('Args:\n') - for arg in argmap.iterkeys(): - if arg in STACK_QUERY_PARAMETERS: - continue - repeated = '' - if arg in repeated_params: - repeated = ' (repeated)' - required = '' - if arg in required_params: - required = ' (required)' - paramdesc = methodDesc['parameters'][argmap[arg]] - paramdoc = paramdesc.get('description', 'A parameter') - if '$ref' in paramdesc: - docs.append( - (' %s: object, %s%s%s\n The object takes the' - ' form of:\n\n%s\n\n') % (arg, paramdoc, required, repeated, - schema.prettyPrintByName(paramdesc['$ref']))) - else: - paramtype = paramdesc.get('type', 'string') - docs.append(' %s: %s, %s%s%s\n' % (arg, paramtype, paramdoc, required, - repeated)) - enum = paramdesc.get('enum', []) - enumDesc = paramdesc.get('enumDescriptions', []) - if enum and enumDesc: - docs.append(' Allowed values\n') - for (name, desc) in zip(enum, enumDesc): - docs.append(' %s - %s\n' % (name, desc)) - if 'response' in methodDesc: - docs.append('\nReturns:\n An object of the form\n\n ') - docs.append(schema.prettyPrintSchema(methodDesc['response'])) - - setattr(method, '__doc__', ''.join(docs)) - setattr(theclass, methodName, method) - - def createNextMethodFromFuture(theclass, methodName, methodDesc, futureDesc): - """ This is a legacy method, as only Buzz and Moderator use the future.json - functionality for generating _next methods. It will be kept around as long - as those API versions are around, but no new APIs should depend upon it. - """ - methodName = _fix_method_name(methodName) - methodId = methodDesc['id'] + '.next' - - def methodNext(self, previous): - """Retrieve the next page of results. - - Takes a single argument, 'body', which is the results - from the last call, and returns the next set of items - in the collection. - - Returns: - None if there are no more items in the collection. - """ - if futureDesc['type'] != 'uri': - raise UnknownLinkType(futureDesc['type']) - - try: - p = previous - for key in futureDesc['location']: - p = p[key] - url = p - except (KeyError, TypeError): - return None - - url = _add_query_parameter(url, 'key', self._developerKey) - - headers = {} - headers, params, query, body = self._model.request(headers, {}, {}, None) - - logging.info('URL being requested: %s' % url) - resp, content = self._http.request(url, method='GET', headers=headers) - - return self._requestBuilder(self._http, - self._model.response, - url, - method='GET', - headers=headers, - methodId=methodId) - - setattr(theclass, methodName, methodNext) - - def createNextMethod(theclass, methodName, methodDesc, futureDesc): - methodName = _fix_method_name(methodName) - methodId = methodDesc['id'] + '.next' - - def methodNext(self, previous_request, previous_response): - """Retrieves the next page of results. - - Args: - previous_request: The request for the previous page. - previous_response: The response from the request for the previous page. - - Returns: - A request object that you can call 'execute()' on to request the next - page. Returns None if there are no more items in the collection. - """ - # Retrieve nextPageToken from previous_response - # Use as pageToken in previous_request to create new request. - - if 'nextPageToken' not in previous_response: - return None - - request = copy.copy(previous_request) - - pageToken = previous_response['nextPageToken'] - parsed = list(urlparse.urlparse(request.uri)) - q = parse_qsl(parsed[4]) - - # Find and remove old 'pageToken' value from URI - newq = [(key, value) for (key, value) in q if key != 'pageToken'] - newq.append(('pageToken', pageToken)) - parsed[4] = urllib.urlencode(newq) - uri = urlparse.urlunparse(parsed) - - request.uri = uri - - logging.info('URL being requested: %s' % uri) - - return request - - setattr(theclass, methodName, methodNext) - - # Add basic methods to Resource - if 'methods' in resourceDesc: - for methodName, methodDesc in resourceDesc['methods'].iteritems(): - if futureDesc: - future = futureDesc['methods'].get(methodName, {}) - else: - future = None - createMethod(Resource, methodName, methodDesc, future) - - # Add in nested resources - if 'resources' in resourceDesc: - - def createResourceMethod(theclass, methodName, methodDesc, futureDesc): - methodName = _fix_method_name(methodName) - - def methodResource(self): - return createResource(self._http, self._baseUrl, self._model, - self._requestBuilder, self._developerKey, - methodDesc, futureDesc, schema) - - setattr(methodResource, '__doc__', 'A collection resource.') - setattr(methodResource, '__is_resource__', True) - setattr(theclass, methodName, methodResource) - - for methodName, methodDesc in resourceDesc['resources'].iteritems(): - if futureDesc and 'resources' in futureDesc: - future = futureDesc['resources'].get(methodName, {}) - else: - future = {} - createResourceMethod(Resource, methodName, methodDesc, future) - - # Add _next() methods to Resource - if futureDesc and 'methods' in futureDesc: - for methodName, methodDesc in futureDesc['methods'].iteritems(): - if 'next' in methodDesc and methodName in resourceDesc['methods']: - createNextMethodFromFuture(Resource, methodName + '_next', - resourceDesc['methods'][methodName], - methodDesc['next']) - # Add _next() methods - # Look for response bodies in schema that contain nextPageToken, and methods - # that take a pageToken parameter. - if 'methods' in resourceDesc: - for methodName, methodDesc in resourceDesc['methods'].iteritems(): - if 'response' in methodDesc: - responseSchema = methodDesc['response'] - if '$ref' in responseSchema: - responseSchema = schema.get(responseSchema['$ref']) - hasNextPageToken = 'nextPageToken' in responseSchema.get('properties', - {}) - hasPageToken = 'pageToken' in methodDesc.get('parameters', {}) - if hasNextPageToken and hasPageToken: - createNextMethod(Resource, methodName + '_next', - resourceDesc['methods'][methodName], - methodName) - - return Resource() Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/discovery.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/discovery.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/errors.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/errors.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/errors.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/errors.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,123 +0,0 @@ -#!/usr/bin/python2.4 -# -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Errors for the library. - -All exceptions defined by the library -should be defined in this file. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - - -from oauth2client.anyjson import simplejson - - -class Error(Exception): - """Base error for this module.""" - pass - - -class HttpError(Error): - """HTTP data was invalid or unexpected.""" - - def __init__(self, resp, content, uri=None): - self.resp = resp - self.content = content - self.uri = uri - - def _get_reason(self): - """Calculate the reason for the error from the response content.""" - if self.resp.get('content-type', '').startswith('application/json'): - try: - data = simplejson.loads(self.content) - reason = data['error']['message'] - except (ValueError, KeyError): - reason = self.content - else: - reason = self.resp.reason - return reason - - def __repr__(self): - if self.uri: - return '' % ( - self.resp.status, self.uri, self._get_reason()) - else: - return '' % (self.resp.status, self._get_reason()) - - __str__ = __repr__ - - -class InvalidJsonError(Error): - """The JSON returned could not be parsed.""" - pass - - -class UnknownLinkType(Error): - """Link type unknown or unexpected.""" - pass - - -class UnknownApiNameOrVersion(Error): - """No API with that name and version exists.""" - pass - - -class UnacceptableMimeTypeError(Error): - """That is an unacceptable mimetype for this operation.""" - pass - - -class MediaUploadSizeError(Error): - """Media is larger than the method can accept.""" - pass - - -class ResumableUploadError(Error): - """Error occured during resumable upload.""" - pass - - -class BatchError(HttpError): - """Error occured during batch operations.""" - - def __init__(self, reason, resp=None, content=None): - self.resp = resp - self.content = content - self.reason = reason - - def __repr__(self): - return '' % (self.resp.status, self.reason) - - __str__ = __repr__ - - -class UnexpectedMethodError(Error): - """Exception raised by RequestMockBuilder on unexpected calls.""" - - def __init__(self, methodId=None): - """Constructor for an UnexpectedMethodError.""" - super(UnexpectedMethodError, self).__init__( - 'Received unexpected call %s' % methodId) - - -class UnexpectedBodyError(Error): - """Exception raised by RequestMockBuilder on unexpected bodies.""" - - def __init__(self, expected, provided): - """Constructor for an UnexpectedMethodError.""" - super(UnexpectedBodyError, self).__init__( - 'Expected: [%s] - Provided: [%s]' % (expected, provided)) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/errors.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/errors.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/appengine.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/appengine.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/appengine.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/appengine.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,135 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for Google App Engine - -Utilities for making it easier to use the -Google API Client for Python on Google App Engine. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import pickle - -from google.appengine.ext import db -from apiclient.oauth import OAuthCredentials -from apiclient.oauth import FlowThreeLegged - - -class FlowThreeLeggedProperty(db.Property): - """Utility property that allows easy - storage and retreival of an - apiclient.oauth.FlowThreeLegged""" - - # Tell what the user type is. - data_type = FlowThreeLegged - - # For writing to datastore. - def get_value_for_datastore(self, model_instance): - flow = super(FlowThreeLeggedProperty, - self).get_value_for_datastore(model_instance) - return db.Blob(pickle.dumps(flow)) - - # For reading from datastore. - def make_value_from_datastore(self, value): - if value is None: - return None - return pickle.loads(value) - - def validate(self, value): - if value is not None and not isinstance(value, FlowThreeLegged): - raise BadValueError('Property %s must be convertible ' - 'to a FlowThreeLegged instance (%s)' % - (self.name, value)) - return super(FlowThreeLeggedProperty, self).validate(value) - - def empty(self, value): - return not value - - -class OAuthCredentialsProperty(db.Property): - """Utility property that allows easy - storage and retrieval of - apiclient.oath.OAuthCredentials - """ - - # Tell what the user type is. - data_type = OAuthCredentials - - # For writing to datastore. - def get_value_for_datastore(self, model_instance): - cred = super(OAuthCredentialsProperty, - self).get_value_for_datastore(model_instance) - return db.Blob(pickle.dumps(cred)) - - # For reading from datastore. - def make_value_from_datastore(self, value): - if value is None: - return None - return pickle.loads(value) - - def validate(self, value): - if value is not None and not isinstance(value, OAuthCredentials): - raise BadValueError('Property %s must be convertible ' - 'to an OAuthCredentials instance (%s)' % - (self.name, value)) - return super(OAuthCredentialsProperty, self).validate(value) - - def empty(self, value): - return not value - - -class StorageByKeyName(object): - """Store and retrieve a single credential to and from - the App Engine datastore. - - This Storage helper presumes the Credentials - have been stored as a CredenialsProperty - on a datastore model class, and that entities - are stored by key_name. - """ - - def __init__(self, model, key_name, property_name): - """Constructor for Storage. - - Args: - model: db.Model, model class - key_name: string, key name for the entity that has the credentials - property_name: string, name of the property that is a CredentialsProperty - """ - self.model = model - self.key_name = key_name - self.property_name = property_name - - def get(self): - """Retrieve Credential from datastore. - - Returns: - Credentials - """ - entity = self.model.get_or_insert(self.key_name) - credential = getattr(entity, self.property_name) - if credential and hasattr(credential, 'set_store'): - credential.set_store(self.put) - return credential - - def put(self, credentials): - """Write a Credentials to the datastore. - - Args: - credentials: Credentials, the credentials to store. - """ - entity = self.model.get_or_insert(self.key_name) - setattr(entity, self.property_name, credentials) - entity.put() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/authtools.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/authtools.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/authtools.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/authtools.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,159 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Command-line tools for authenticating via OAuth 1.0 - -Do the OAuth 1.0 Three Legged Dance for -a command line application. Stores the generated -credentials in a common file that is used by -other example apps in the same directory. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' -__all__ = ["run"] - -import BaseHTTPServer -import gflags -import logging -import socket -import sys - -from optparse import OptionParser -from apiclient.oauth import RequestError - -try: - from urlparse import parse_qsl -except ImportError: - from cgi import parse_qsl - - -FLAGS = gflags.FLAGS - -gflags.DEFINE_boolean('auth_local_webserver', True, - ('Run a local web server to handle redirects during ' - 'OAuth authorization.')) - -gflags.DEFINE_string('auth_host_name', 'localhost', - ('Host name to use when running a local web server to ' - 'handle redirects during OAuth authorization.')) - -gflags.DEFINE_multi_int('auth_host_port', [8080, 8090], - ('Port to use when running a local web server to ' - 'handle redirects during OAuth authorization.')) - - -class ClientRedirectServer(BaseHTTPServer.HTTPServer): - """A server to handle OAuth 1.0 redirects back to localhost. - - Waits for a single request and parses the query parameters - into query_params and then stops serving. - """ - query_params = {} - - -class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler): - """A handler for OAuth 1.0 redirects back to localhost. - - Waits for a single request and parses the query parameters - into the servers query_params and then stops serving. - """ - - def do_GET(s): - """Handle a GET request - - Parses the query parameters and prints a message - if the flow has completed. Note that we can't detect - if an error occurred. - """ - s.send_response(200) - s.send_header("Content-type", "text/html") - s.end_headers() - query = s.path.split('?', 1)[-1] - query = dict(parse_qsl(query)) - s.server.query_params = query - s.wfile.write("Authentication Status") - s.wfile.write("

The authentication flow has completed.

") - s.wfile.write("") - - def log_message(self, format, *args): - """Do not log messages to stdout while running as command line program.""" - pass - - -def run(flow, storage): - """Core code for a command-line application. - - Args: - flow: Flow, an OAuth 1.0 Flow to step through. - storage: Storage, a Storage to store the credential in. - - Returns: - Credentials, the obtained credential. - - Exceptions: - RequestError: if step2 of the flow fails. - Args: - """ - - if FLAGS.auth_local_webserver: - success = False - port_number = 0 - for port in FLAGS.auth_host_port: - port_number = port - try: - httpd = BaseHTTPServer.HTTPServer((FLAGS.auth_host_name, port), - ClientRedirectHandler) - except socket.error, e: - pass - else: - success = True - break - FLAGS.auth_local_webserver = success - - if FLAGS.auth_local_webserver: - oauth_callback = 'http://%s:%s/' % (FLAGS.auth_host_name, port_number) - else: - oauth_callback = 'oob' - authorize_url = flow.step1_get_authorize_url(oauth_callback) - - print 'Go to the following link in your browser:' - print authorize_url - print - if FLAGS.auth_local_webserver: - print 'If your browser is on a different machine then exit and re-run this' - print 'application with the command-line parameter --noauth_local_webserver.' - print - - if FLAGS.auth_local_webserver: - httpd.handle_request() - if 'error' in httpd.query_params: - sys.exit('Authentication request was rejected.') - if 'oauth_verifier' in httpd.query_params: - code = httpd.query_params['oauth_verifier'] - else: - accepted = 'n' - while accepted.lower() == 'n': - accepted = raw_input('Have you authorized me? (y/n) ') - code = raw_input('What is the verification code? ').strip() - - try: - credentials = flow.step2_exchange(code) - except RequestError: - sys.exit('The authentication has failed.') - - storage.put(credentials) - credentials.set_store(storage.put) - print "You have successfully authenticated." - - return credentials diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/django_orm.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/django_orm.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/django_orm.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/django_orm.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,56 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import apiclient -import base64 -import pickle - -from django.db import models - - -class OAuthCredentialsField(models.Field): - - __metaclass__ = models.SubfieldBase - - def db_type(self): - return 'VARCHAR' - - def to_python(self, value): - if value is None: - return None - if isinstance(value, apiclient.oauth.Credentials): - return value - return pickle.loads(base64.b64decode(value)) - - def get_db_prep_value(self, value): - return base64.b64encode(pickle.dumps(value)) - - -class FlowThreeLeggedField(models.Field): - - __metaclass__ = models.SubfieldBase - - def db_type(self): - return 'VARCHAR' - - def to_python(self, value): - print "In to_python", value - if value is None: - return None - if isinstance(value, apiclient.oauth.FlowThreeLegged): - return value - return pickle.loads(base64.b64decode(value)) - - def get_db_prep_value(self, value): - return base64.b64encode(pickle.dumps(value)) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/file.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/file.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/ext/file.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/ext/file.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,63 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for OAuth. - -Utilities for making it easier to work with OAuth 1.0 credentials. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import pickle -import threading - -from apiclient.oauth import Storage as BaseStorage - - -class Storage(BaseStorage): - """Store and retrieve a single credential to and from a file.""" - - def __init__(self, filename): - self._filename = filename - self._lock = threading.Lock() - - def get(self): - """Retrieve Credential from file. - - Returns: - apiclient.oauth.Credentials - """ - self._lock.acquire() - try: - f = open(self._filename, 'r') - credentials = pickle.loads(f.read()) - f.close() - credentials.set_store(self.put) - except: - credentials = None - self._lock.release() - - return credentials - - def put(self, credentials): - """Write a pickled Credentials to file. - - Args: - credentials: Credentials, the credentials to store. - """ - self._lock.acquire() - f = open(self._filename, 'w') - f.write(pickle.dumps(credentials)) - f.close() - self._lock.release() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/http.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/http.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/http.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/http.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1104 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Classes to encapsulate a single HTTP request. - -The classes implement a command pattern, with every -object supporting an execute() method that does the -actuall HTTP request. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' -__all__ = [ - 'HttpRequest', 'RequestMockBuilder', 'HttpMock' - 'set_user_agent', 'tunnel_patch' - ] - -import StringIO -import base64 -import copy -import gzip -import httplib2 -import mimeparse -import mimetypes -import os -import urllib -import urlparse -import uuid - -from email.generator import Generator -from email.mime.multipart import MIMEMultipart -from email.mime.nonmultipart import MIMENonMultipart -from email.parser import FeedParser -from errors import BatchError -from errors import HttpError -from errors import ResumableUploadError -from errors import UnexpectedBodyError -from errors import UnexpectedMethodError -from model import JsonModel -from oauth2client.anyjson import simplejson - - -class MediaUploadProgress(object): - """Status of a resumable upload.""" - - def __init__(self, resumable_progress, total_size): - """Constructor. - - Args: - resumable_progress: int, bytes sent so far. - total_size: int, total bytes in complete upload. - """ - self.resumable_progress = resumable_progress - self.total_size = total_size - - def progress(self): - """Percent of upload completed, as a float.""" - return float(self.resumable_progress) / float(self.total_size) - - -class MediaUpload(object): - """Describes a media object to upload. - - Base class that defines the interface of MediaUpload subclasses. - """ - - def getbytes(self, begin, end): - raise NotImplementedError() - - def size(self): - raise NotImplementedError() - - def chunksize(self): - raise NotImplementedError() - - def mimetype(self): - return 'application/octet-stream' - - def resumable(self): - return False - - def _to_json(self, strip=None): - """Utility function for creating a JSON representation of a MediaUpload. - - Args: - strip: array, An array of names of members to not include in the JSON. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - t = type(self) - d = copy.copy(self.__dict__) - if strip is not None: - for member in strip: - del d[member] - d['_class'] = t.__name__ - d['_module'] = t.__module__ - return simplejson.dumps(d) - - def to_json(self): - """Create a JSON representation of an instance of MediaUpload. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - return self._to_json() - - @classmethod - def new_from_json(cls, s): - """Utility class method to instantiate a MediaUpload subclass from a JSON - representation produced by to_json(). - - Args: - s: string, JSON from to_json(). - - Returns: - An instance of the subclass of MediaUpload that was serialized with - to_json(). - """ - data = simplejson.loads(s) - # Find and call the right classmethod from_json() to restore the object. - module = data['_module'] - m = __import__(module, fromlist=module.split('.')[:-1]) - kls = getattr(m, data['_class']) - from_json = getattr(kls, 'from_json') - return from_json(s) - - -class MediaFileUpload(MediaUpload): - """A MediaUpload for a file. - - Construct a MediaFileUpload and pass as the media_body parameter of the - method. For example, if we had a service that allowed uploading images: - - - media = MediaFileUpload('smiley.png', mimetype='image/png', chunksize=1000, - resumable=True) - service.objects().insert( - bucket=buckets['items'][0]['id'], - name='smiley.png', - media_body=media).execute() - """ - - def __init__(self, filename, mimetype=None, chunksize=256*1024, resumable=False): - """Constructor. - - Args: - filename: string, Name of the file. - mimetype: string, Mime-type of the file. If None then a mime-type will be - guessed from the file extension. - chunksize: int, File will be uploaded in chunks of this many bytes. Only - used if resumable=True. - resumable: bool, True if this is a resumable upload. False means upload - in a single request. - """ - self._filename = filename - self._size = os.path.getsize(filename) - self._fd = None - if mimetype is None: - (mimetype, encoding) = mimetypes.guess_type(filename) - self._mimetype = mimetype - self._chunksize = chunksize - self._resumable = resumable - - def mimetype(self): - return self._mimetype - - def size(self): - return self._size - - def chunksize(self): - return self._chunksize - - def resumable(self): - return self._resumable - - def getbytes(self, begin, length): - """Get bytes from the media. - - Args: - begin: int, offset from beginning of file. - length: int, number of bytes to read, starting at begin. - - Returns: - A string of bytes read. May be shorted than length if EOF was reached - first. - """ - if self._fd is None: - self._fd = open(self._filename, 'rb') - self._fd.seek(begin) - return self._fd.read(length) - - def to_json(self): - """Creating a JSON representation of an instance of Credentials. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - return self._to_json(['_fd']) - - @staticmethod - def from_json(s): - d = simplejson.loads(s) - return MediaFileUpload( - d['_filename'], d['_mimetype'], d['_chunksize'], d['_resumable']) - - -class MediaInMemoryUpload(MediaUpload): - """MediaUpload for a chunk of bytes. - - Construct a MediaFileUpload and pass as the media_body parameter of the - method. For example, if we had a service that allowed plain text: - """ - - def __init__(self, body, mimetype='application/octet-stream', - chunksize=256*1024, resumable=False): - """Create a new MediaBytesUpload. - - Args: - body: string, Bytes of body content. - mimetype: string, Mime-type of the file or default of - 'application/octet-stream'. - chunksize: int, File will be uploaded in chunks of this many bytes. Only - used if resumable=True. - resumable: bool, True if this is a resumable upload. False means upload - in a single request. - """ - self._body = body - self._mimetype = mimetype - self._resumable = resumable - self._chunksize = chunksize - - def chunksize(self): - """Chunk size for resumable uploads. - - Returns: - Chunk size in bytes. - """ - return self._chunksize - - def mimetype(self): - """Mime type of the body. - - Returns: - Mime type. - """ - return self._mimetype - - def size(self): - """Size of upload. - - Returns: - Size of the body. - """ - return len(self.body) - - def resumable(self): - """Whether this upload is resumable. - - Returns: - True if resumable upload or False. - """ - return self._resumable - - def getbytes(self, begin, length): - """Get bytes from the media. - - Args: - begin: int, offset from beginning of file. - length: int, number of bytes to read, starting at begin. - - Returns: - A string of bytes read. May be shorter than length if EOF was reached - first. - """ - return self._body[begin:begin + length] - - def to_json(self): - """Create a JSON representation of a MediaInMemoryUpload. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - t = type(self) - d = copy.copy(self.__dict__) - del d['_body'] - d['_class'] = t.__name__ - d['_module'] = t.__module__ - d['_b64body'] = base64.b64encode(self._body) - return simplejson.dumps(d) - - @staticmethod - def from_json(s): - d = simplejson.loads(s) - return MediaInMemoryUpload(base64.b64decode(d['_b64body']), - d['_mimetype'], d['_chunksize'], - d['_resumable']) - - -class HttpRequest(object): - """Encapsulates a single HTTP request.""" - - def __init__(self, http, postproc, uri, - method='GET', - body=None, - headers=None, - methodId=None, - resumable=None): - """Constructor for an HttpRequest. - - Args: - http: httplib2.Http, the transport object to use to make a request - postproc: callable, called on the HTTP response and content to transform - it into a data object before returning, or raising an exception - on an error. - uri: string, the absolute URI to send the request to - method: string, the HTTP method to use - body: string, the request body of the HTTP request, - headers: dict, the HTTP request headers - methodId: string, a unique identifier for the API method being called. - resumable: MediaUpload, None if this is not a resumbale request. - """ - self.uri = uri - self.method = method - self.body = body - self.headers = headers or {} - self.methodId = methodId - self.http = http - self.postproc = postproc - self.resumable = resumable - - # Pull the multipart boundary out of the content-type header. - major, minor, params = mimeparse.parse_mime_type( - headers.get('content-type', 'application/json')) - - # The size of the non-media part of the request. - self.body_size = len(self.body or '') - - # The resumable URI to send chunks to. - self.resumable_uri = None - - # The bytes that have been uploaded. - self.resumable_progress = 0 - - def execute(self, http=None): - """Execute the request. - - Args: - http: httplib2.Http, an http object to be used in place of the - one the HttpRequest request object was constructed with. - - Returns: - A deserialized object model of the response body as determined - by the postproc. - - Raises: - apiclient.errors.HttpError if the response was not a 2xx. - httplib2.Error if a transport error has occured. - """ - if http is None: - http = self.http - if self.resumable: - body = None - while body is None: - _, body = self.next_chunk(http) - return body - else: - if 'content-length' not in self.headers: - self.headers['content-length'] = str(self.body_size) - resp, content = http.request(self.uri, self.method, - body=self.body, - headers=self.headers) - - if resp.status >= 300: - raise HttpError(resp, content, self.uri) - return self.postproc(resp, content) - - def next_chunk(self, http=None): - """Execute the next step of a resumable upload. - - Can only be used if the method being executed supports media uploads and - the MediaUpload object passed in was flagged as using resumable upload. - - Example: - - media = MediaFileUpload('smiley.png', mimetype='image/png', - chunksize=1000, resumable=True) - request = service.objects().insert( - bucket=buckets['items'][0]['id'], - name='smiley.png', - media_body=media) - - response = None - while response is None: - status, response = request.next_chunk() - if status: - print "Upload %d%% complete." % int(status.progress() * 100) - - - Returns: - (status, body): (ResumableMediaStatus, object) - The body will be None until the resumable media is fully uploaded. - """ - if http is None: - http = self.http - - if self.resumable_uri is None: - start_headers = copy.copy(self.headers) - start_headers['X-Upload-Content-Type'] = self.resumable.mimetype() - start_headers['X-Upload-Content-Length'] = str(self.resumable.size()) - start_headers['content-length'] = str(self.body_size) - - resp, content = http.request(self.uri, self.method, - body=self.body, - headers=start_headers) - if resp.status == 200 and 'location' in resp: - self.resumable_uri = resp['location'] - else: - raise ResumableUploadError("Failed to retrieve starting URI.") - - data = self.resumable.getbytes(self.resumable_progress, - self.resumable.chunksize()) - - headers = { - 'Content-Range': 'bytes %d-%d/%d' % ( - self.resumable_progress, self.resumable_progress + len(data) - 1, - self.resumable.size()), - } - resp, content = http.request(self.resumable_uri, 'PUT', - body=data, - headers=headers) - if resp.status in [200, 201]: - return None, self.postproc(resp, content) - elif resp.status == 308: - # A "308 Resume Incomplete" indicates we are not done. - self.resumable_progress = int(resp['range'].split('-')[1]) + 1 - if 'location' in resp: - self.resumable_uri = resp['location'] - else: - raise HttpError(resp, content, self.uri) - - return (MediaUploadProgress(self.resumable_progress, self.resumable.size()), - None) - - def to_json(self): - """Returns a JSON representation of the HttpRequest.""" - d = copy.copy(self.__dict__) - if d['resumable'] is not None: - d['resumable'] = self.resumable.to_json() - del d['http'] - del d['postproc'] - return simplejson.dumps(d) - - @staticmethod - def from_json(s, http, postproc): - """Returns an HttpRequest populated with info from a JSON object.""" - d = simplejson.loads(s) - if d['resumable'] is not None: - d['resumable'] = MediaUpload.new_from_json(d['resumable']) - return HttpRequest( - http, - postproc, - uri=d['uri'], - method=d['method'], - body=d['body'], - headers=d['headers'], - methodId=d['methodId'], - resumable=d['resumable']) - - -class BatchHttpRequest(object): - """Batches multiple HttpRequest objects into a single HTTP request.""" - - def __init__(self, callback=None, batch_uri=None): - """Constructor for a BatchHttpRequest. - - Args: - callback: callable, A callback to be called for each response, of the - form callback(id, response). The first parameter is the request id, and - the second is the deserialized response object. - batch_uri: string, URI to send batch requests to. - """ - if batch_uri is None: - batch_uri = 'https://www.googleapis.com/batch' - self._batch_uri = batch_uri - - # Global callback to be called for each individual response in the batch. - self._callback = callback - - # A map from id to request. - self._requests = {} - - # A map from id to callback. - self._callbacks = {} - - # List of request ids, in the order in which they were added. - self._order = [] - - # The last auto generated id. - self._last_auto_id = 0 - - # Unique ID on which to base the Content-ID headers. - self._base_id = None - - # A map from request id to (headers, content) response pairs - self._responses = {} - - # A map of id(Credentials) that have been refreshed. - self._refreshed_credentials = {} - - def _refresh_and_apply_credentials(self, request, http): - """Refresh the credentials and apply to the request. - - Args: - request: HttpRequest, the request. - http: httplib2.Http, the global http object for the batch. - """ - # For the credentials to refresh, but only once per refresh_token - # If there is no http per the request then refresh the http passed in - # via execute() - creds = None - if request.http is not None and hasattr(request.http.request, - 'credentials'): - creds = request.http.request.credentials - elif http is not None and hasattr(http.request, 'credentials'): - creds = http.request.credentials - if creds is not None: - if id(creds) not in self._refreshed_credentials: - creds.refresh(http) - self._refreshed_credentials[id(creds)] = 1 - - # Only apply the credentials if we are using the http object passed in, - # otherwise apply() will get called during _serialize_request(). - if request.http is None or not hasattr(request.http.request, - 'credentials'): - creds.apply(request.headers) - - def _id_to_header(self, id_): - """Convert an id to a Content-ID header value. - - Args: - id_: string, identifier of individual request. - - Returns: - A Content-ID header with the id_ encoded into it. A UUID is prepended to - the value because Content-ID headers are supposed to be universally - unique. - """ - if self._base_id is None: - self._base_id = uuid.uuid4() - - return '<%s+%s>' % (self._base_id, urllib.quote(id_)) - - def _header_to_id(self, header): - """Convert a Content-ID header value to an id. - - Presumes the Content-ID header conforms to the format that _id_to_header() - returns. - - Args: - header: string, Content-ID header value. - - Returns: - The extracted id value. - - Raises: - BatchError if the header is not in the expected format. - """ - if header[0] != '<' or header[-1] != '>': - raise BatchError("Invalid value for Content-ID: %s" % header) - if '+' not in header: - raise BatchError("Invalid value for Content-ID: %s" % header) - base, id_ = header[1:-1].rsplit('+', 1) - - return urllib.unquote(id_) - - def _serialize_request(self, request): - """Convert an HttpRequest object into a string. - - Args: - request: HttpRequest, the request to serialize. - - Returns: - The request as a string in application/http format. - """ - # Construct status line - parsed = urlparse.urlparse(request.uri) - request_line = urlparse.urlunparse( - (None, None, parsed.path, parsed.params, parsed.query, None) - ) - status_line = request.method + ' ' + request_line + ' HTTP/1.1\n' - major, minor = request.headers.get('content-type', 'application/json').split('/') - msg = MIMENonMultipart(major, minor) - headers = request.headers.copy() - - if request.http is not None and hasattr(request.http.request, - 'credentials'): - request.http.request.credentials.apply(headers) - - # MIMENonMultipart adds its own Content-Type header. - if 'content-type' in headers: - del headers['content-type'] - - for key, value in headers.iteritems(): - msg[key] = value - msg['Host'] = parsed.netloc - msg.set_unixfrom(None) - - if request.body is not None: - msg.set_payload(request.body) - msg['content-length'] = str(len(request.body)) - - # Serialize the mime message. - fp = StringIO.StringIO() - # maxheaderlen=0 means don't line wrap headers. - g = Generator(fp, maxheaderlen=0) - g.flatten(msg, unixfrom=False) - body = fp.getvalue() - - # Strip off the \n\n that the MIME lib tacks onto the end of the payload. - if request.body is None: - body = body[:-2] - - return status_line.encode('utf-8') + body - - def _deserialize_response(self, payload): - """Convert string into httplib2 response and content. - - Args: - payload: string, headers and body as a string. - - Returns: - A pair (resp, content) like would be returned from httplib2.request. - """ - # Strip off the status line - status_line, payload = payload.split('\n', 1) - protocol, status, reason = status_line.split(' ', 2) - - # Parse the rest of the response - parser = FeedParser() - parser.feed(payload) - msg = parser.close() - msg['status'] = status - - # Create httplib2.Response from the parsed headers. - resp = httplib2.Response(msg) - resp.reason = reason - resp.version = int(protocol.split('/', 1)[1].replace('.', '')) - - content = payload.split('\r\n\r\n', 1)[1] - - return resp, content - - def _new_id(self): - """Create a new id. - - Auto incrementing number that avoids conflicts with ids already used. - - Returns: - string, a new unique id. - """ - self._last_auto_id += 1 - while str(self._last_auto_id) in self._requests: - self._last_auto_id += 1 - return str(self._last_auto_id) - - def add(self, request, callback=None, request_id=None): - """Add a new request. - - Every callback added will be paired with a unique id, the request_id. That - unique id will be passed back to the callback when the response comes back - from the server. The default behavior is to have the library generate it's - own unique id. If the caller passes in a request_id then they must ensure - uniqueness for each request_id, and if they are not an exception is - raised. Callers should either supply all request_ids or nevery supply a - request id, to avoid such an error. - - Args: - request: HttpRequest, Request to add to the batch. - callback: callable, A callback to be called for this response, of the - form callback(id, response). The first parameter is the request id, and - the second is the deserialized response object. - request_id: string, A unique id for the request. The id will be passed to - the callback with the response. - - Returns: - None - - Raises: - BatchError if a resumable request is added to a batch. - KeyError is the request_id is not unique. - """ - if request_id is None: - request_id = self._new_id() - if request.resumable is not None: - raise BatchError("Resumable requests cannot be used in a batch request.") - if request_id in self._requests: - raise KeyError("A request with this ID already exists: %s" % request_id) - self._requests[request_id] = request - self._callbacks[request_id] = callback - self._order.append(request_id) - - def _execute(self, http, order, requests): - """Serialize batch request, send to server, process response. - - Args: - http: httplib2.Http, an http object to be used to make the request with. - order: list, list of request ids in the order they were added to the - batch. - request: list, list of request objects to send. - - Raises: - httplib2.Error if a transport error has occured. - apiclient.errors.BatchError if the response is the wrong format. - """ - message = MIMEMultipart('mixed') - # Message should not write out it's own headers. - setattr(message, '_write_headers', lambda self: None) - - # Add all the individual requests. - for request_id in order: - request = requests[request_id] - - msg = MIMENonMultipart('application', 'http') - msg['Content-Transfer-Encoding'] = 'binary' - msg['Content-ID'] = self._id_to_header(request_id) - - body = self._serialize_request(request) - msg.set_payload(body) - message.attach(msg) - - body = message.as_string() - - headers = {} - headers['content-type'] = ('multipart/mixed; ' - 'boundary="%s"') % message.get_boundary() - - resp, content = http.request(self._batch_uri, 'POST', body=body, - headers=headers) - - if resp.status >= 300: - raise HttpError(resp, content, self._batch_uri) - - # Now break out the individual responses and store each one. - boundary, _ = content.split(None, 1) - - # Prepend with a content-type header so FeedParser can handle it. - header = 'content-type: %s\r\n\r\n' % resp['content-type'] - for_parser = header + content - - parser = FeedParser() - parser.feed(for_parser) - mime_response = parser.close() - - if not mime_response.is_multipart(): - raise BatchError("Response not in multipart/mixed format.", resp, - content) - - for part in mime_response.get_payload(): - request_id = self._header_to_id(part['Content-ID']) - headers, content = self._deserialize_response(part.get_payload()) - self._responses[request_id] = (headers, content) - - def execute(self, http=None): - """Execute all the requests as a single batched HTTP request. - - Args: - http: httplib2.Http, an http object to be used in place of the one the - HttpRequest request object was constructed with. If one isn't supplied - then use a http object from the requests in this batch. - - Returns: - None - - Raises: - httplib2.Error if a transport error has occured. - apiclient.errors.BatchError if the response is the wrong format. - """ - - # If http is not supplied use the first valid one given in the requests. - if http is None: - for request_id in self._order: - request = self._requests[request_id] - if request is not None: - http = request.http - break - - if http is None: - raise ValueError("Missing a valid http object.") - - self._execute(http, self._order, self._requests) - - # Loop over all the requests and check for 401s. For each 401 request the - # credentials should be refreshed and then sent again in a separate batch. - redo_requests = {} - redo_order = [] - - for request_id in self._order: - headers, content = self._responses[request_id] - if headers['status'] == '401': - redo_order.append(request_id) - request = self._requests[request_id] - self._refresh_and_apply_credentials(request, http) - redo_requests[request_id] = request - - if redo_requests: - self._execute(http, redo_order, redo_requests) - - # Now process all callbacks that are erroring, and raise an exception for - # ones that return a non-2xx response? Or add extra parameter to callback - # that contains an HttpError? - - for request_id in self._order: - headers, content = self._responses[request_id] - - request = self._requests[request_id] - callback = self._callbacks[request_id] - - response = None - exception = None - try: - r = httplib2.Response(headers) - response = request.postproc(r, content) - except HttpError, e: - exception = e - - if callback is not None: - callback(request_id, response, exception) - if self._callback is not None: - self._callback(request_id, response, exception) - - -class HttpRequestMock(object): - """Mock of HttpRequest. - - Do not construct directly, instead use RequestMockBuilder. - """ - - def __init__(self, resp, content, postproc): - """Constructor for HttpRequestMock - - Args: - resp: httplib2.Response, the response to emulate coming from the request - content: string, the response body - postproc: callable, the post processing function usually supplied by - the model class. See model.JsonModel.response() as an example. - """ - self.resp = resp - self.content = content - self.postproc = postproc - if resp is None: - self.resp = httplib2.Response({'status': 200, 'reason': 'OK'}) - if 'reason' in self.resp: - self.resp.reason = self.resp['reason'] - - def execute(self, http=None): - """Execute the request. - - Same behavior as HttpRequest.execute(), but the response is - mocked and not really from an HTTP request/response. - """ - return self.postproc(self.resp, self.content) - - -class RequestMockBuilder(object): - """A simple mock of HttpRequest - - Pass in a dictionary to the constructor that maps request methodIds to - tuples of (httplib2.Response, content, opt_expected_body) that should be - returned when that method is called. None may also be passed in for the - httplib2.Response, in which case a 200 OK response will be generated. - If an opt_expected_body (str or dict) is provided, it will be compared to - the body and UnexpectedBodyError will be raised on inequality. - - Example: - response = '{"data": {"id": "tag:google.c...' - requestBuilder = RequestMockBuilder( - { - 'plus.activities.get': (None, response), - } - ) - apiclient.discovery.build("plus", "v1", requestBuilder=requestBuilder) - - Methods that you do not supply a response for will return a - 200 OK with an empty string as the response content or raise an excpetion - if check_unexpected is set to True. The methodId is taken from the rpcName - in the discovery document. - - For more details see the project wiki. - """ - - def __init__(self, responses, check_unexpected=False): - """Constructor for RequestMockBuilder - - The constructed object should be a callable object - that can replace the class HttpResponse. - - responses - A dictionary that maps methodIds into tuples - of (httplib2.Response, content). The methodId - comes from the 'rpcName' field in the discovery - document. - check_unexpected - A boolean setting whether or not UnexpectedMethodError - should be raised on unsupplied method. - """ - self.responses = responses - self.check_unexpected = check_unexpected - - def __call__(self, http, postproc, uri, method='GET', body=None, - headers=None, methodId=None, resumable=None): - """Implements the callable interface that discovery.build() expects - of requestBuilder, which is to build an object compatible with - HttpRequest.execute(). See that method for the description of the - parameters and the expected response. - """ - if methodId in self.responses: - response = self.responses[methodId] - resp, content = response[:2] - if len(response) > 2: - # Test the body against the supplied expected_body. - expected_body = response[2] - if bool(expected_body) != bool(body): - # Not expecting a body and provided one - # or expecting a body and not provided one. - raise UnexpectedBodyError(expected_body, body) - if isinstance(expected_body, str): - expected_body = simplejson.loads(expected_body) - body = simplejson.loads(body) - if body != expected_body: - raise UnexpectedBodyError(expected_body, body) - return HttpRequestMock(resp, content, postproc) - elif self.check_unexpected: - raise UnexpectedMethodError(methodId) - else: - model = JsonModel(False) - return HttpRequestMock(None, '{}', model.response) - - -class HttpMock(object): - """Mock of httplib2.Http""" - - def __init__(self, filename, headers=None): - """ - Args: - filename: string, absolute filename to read response from - headers: dict, header to return with response - """ - if headers is None: - headers = {'status': '200 OK'} - f = file(filename, 'r') - self.data = f.read() - f.close() - self.headers = headers - - def request(self, uri, - method='GET', - body=None, - headers=None, - redirections=1, - connection_type=None): - return httplib2.Response(self.headers), self.data - - -class HttpMockSequence(object): - """Mock of httplib2.Http - - Mocks a sequence of calls to request returning different responses for each - call. Create an instance initialized with the desired response headers - and content and then use as if an httplib2.Http instance. - - http = HttpMockSequence([ - ({'status': '401'}, ''), - ({'status': '200'}, '{"access_token":"1/3w","expires_in":3600}'), - ({'status': '200'}, 'echo_request_headers'), - ]) - resp, content = http.request("http://examples.com") - - There are special values you can pass in for content to trigger - behavours that are helpful in testing. - - 'echo_request_headers' means return the request headers in the response body - 'echo_request_headers_as_json' means return the request headers in - the response body - 'echo_request_body' means return the request body in the response body - 'echo_request_uri' means return the request uri in the response body - """ - - def __init__(self, iterable): - """ - Args: - iterable: iterable, a sequence of pairs of (headers, body) - """ - self._iterable = iterable - - def request(self, uri, - method='GET', - body=None, - headers=None, - redirections=1, - connection_type=None): - resp, content = self._iterable.pop(0) - if content == 'echo_request_headers': - content = headers - elif content == 'echo_request_headers_as_json': - content = simplejson.dumps(headers) - elif content == 'echo_request_body': - content = body - elif content == 'echo_request_uri': - content = uri - return httplib2.Response(resp), content - - -def set_user_agent(http, user_agent): - """Set the user-agent on every request. - - Args: - http - An instance of httplib2.Http - or something that acts like it. - user_agent: string, the value for the user-agent header. - - Returns: - A modified instance of http that was passed in. - - Example: - - h = httplib2.Http() - h = set_user_agent(h, "my-app-name/6.0") - - Most of the time the user-agent will be set doing auth, this is for the rare - cases where you are accessing an unauthenticated endpoint. - """ - request_orig = http.request - - # The closure that will replace 'httplib2.Http.request'. - def new_request(uri, method='GET', body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, - connection_type=None): - """Modify the request headers to add the user-agent.""" - if headers is None: - headers = {} - if 'user-agent' in headers: - headers['user-agent'] = user_agent + ' ' + headers['user-agent'] - else: - headers['user-agent'] = user_agent - resp, content = request_orig(uri, method, body, headers, - redirections, connection_type) - return resp, content - - http.request = new_request - return http - - -def tunnel_patch(http): - """Tunnel PATCH requests over POST. - Args: - http - An instance of httplib2.Http - or something that acts like it. - - Returns: - A modified instance of http that was passed in. - - Example: - - h = httplib2.Http() - h = tunnel_patch(h, "my-app-name/6.0") - - Useful if you are running on a platform that doesn't support PATCH. - Apply this last if you are using OAuth 1.0, as changing the method - will result in a different signature. - """ - request_orig = http.request - - # The closure that will replace 'httplib2.Http.request'. - def new_request(uri, method='GET', body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, - connection_type=None): - """Modify the request headers to add the user-agent.""" - if headers is None: - headers = {} - if method == 'PATCH': - if 'oauth_token' in headers.get('authorization', ''): - logging.warning( - 'OAuth 1.0 request made with Credentials after tunnel_patch.') - headers['x-http-method-override'] = "PATCH" - method = 'POST' - resp, content = request_orig(uri, method, body, headers, - redirections, connection_type) - return resp, content - - http.request = new_request - return http Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/http.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/http.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/mimeparse.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/mimeparse.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/mimeparse.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/mimeparse.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ -# Copyright (C) 2007 Joe Gregorio -# -# Licensed under the MIT License - -"""MIME-Type Parser - -This module provides basic functions for handling mime-types. It can handle -matching mime-types against a list of media-ranges. See section 14.1 of the -HTTP specification [RFC 2616] for a complete explanation. - - http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 - -Contents: - - parse_mime_type(): Parses a mime-type into its component parts. - - parse_media_range(): Media-ranges are mime-types with wild-cards and a 'q' - quality parameter. - - quality(): Determines the quality ('q') of a mime-type when - compared against a list of media-ranges. - - quality_parsed(): Just like quality() except the second parameter must be - pre-parsed. - - best_match(): Choose the mime-type with the highest quality ('q') - from a list of candidates. -""" - -__version__ = '0.1.3' -__author__ = 'Joe Gregorio' -__email__ = 'joe@bitworking.org' -__license__ = 'MIT License' -__credits__ = '' - - -def parse_mime_type(mime_type): - """Parses a mime-type into its component parts. - - Carves up a mime-type and returns a tuple of the (type, subtype, params) - where 'params' is a dictionary of all the parameters for the media range. - For example, the media range 'application/xhtml;q=0.5' would get parsed - into: - - ('application', 'xhtml', {'q', '0.5'}) - """ - parts = mime_type.split(';') - params = dict([tuple([s.strip() for s in param.split('=', 1)])\ - for param in parts[1:] - ]) - full_type = parts[0].strip() - # Java URLConnection class sends an Accept header that includes a - # single '*'. Turn it into a legal wildcard. - if full_type == '*': - full_type = '*/*' - (type, subtype) = full_type.split('/') - - return (type.strip(), subtype.strip(), params) - - -def parse_media_range(range): - """Parse a media-range into its component parts. - - Carves up a media range and returns a tuple of the (type, subtype, - params) where 'params' is a dictionary of all the parameters for the media - range. For example, the media range 'application/*;q=0.5' would get parsed - into: - - ('application', '*', {'q', '0.5'}) - - In addition this function also guarantees that there is a value for 'q' - in the params dictionary, filling it in with a proper default if - necessary. - """ - (type, subtype, params) = parse_mime_type(range) - if not params.has_key('q') or not params['q'] or \ - not float(params['q']) or float(params['q']) > 1\ - or float(params['q']) < 0: - params['q'] = '1' - - return (type, subtype, params) - - -def fitness_and_quality_parsed(mime_type, parsed_ranges): - """Find the best match for a mime-type amongst parsed media-ranges. - - Find the best match for a given mime-type against a list of media_ranges - that have already been parsed by parse_media_range(). Returns a tuple of - the fitness value and the value of the 'q' quality parameter of the best - match, or (-1, 0) if no match was found. Just as for quality_parsed(), - 'parsed_ranges' must be a list of parsed media ranges. - """ - best_fitness = -1 - best_fit_q = 0 - (target_type, target_subtype, target_params) =\ - parse_media_range(mime_type) - for (type, subtype, params) in parsed_ranges: - type_match = (type == target_type or\ - type == '*' or\ - target_type == '*') - subtype_match = (subtype == target_subtype or\ - subtype == '*' or\ - target_subtype == '*') - if type_match and subtype_match: - param_matches = reduce(lambda x, y: x + y, [1 for (key, value) in \ - target_params.iteritems() if key != 'q' and \ - params.has_key(key) and value == params[key]], 0) - fitness = (type == target_type) and 100 or 0 - fitness += (subtype == target_subtype) and 10 or 0 - fitness += param_matches - if fitness > best_fitness: - best_fitness = fitness - best_fit_q = params['q'] - - return best_fitness, float(best_fit_q) - - -def quality_parsed(mime_type, parsed_ranges): - """Find the best match for a mime-type amongst parsed media-ranges. - - Find the best match for a given mime-type against a list of media_ranges - that have already been parsed by parse_media_range(). Returns the 'q' - quality parameter of the best match, 0 if no match was found. This function - bahaves the same as quality() except that 'parsed_ranges' must be a list of - parsed media ranges. - """ - - return fitness_and_quality_parsed(mime_type, parsed_ranges)[1] - - -def quality(mime_type, ranges): - """Return the quality ('q') of a mime-type against a list of media-ranges. - - Returns the quality 'q' of a mime-type when compared against the - media-ranges in ranges. For example: - - >>> quality('text/html','text/*;q=0.3, text/html;q=0.7, - text/html;level=1, text/html;level=2;q=0.4, */*;q=0.5') - 0.7 - - """ - parsed_ranges = [parse_media_range(r) for r in ranges.split(',')] - - return quality_parsed(mime_type, parsed_ranges) - - -def best_match(supported, header): - """Return mime-type with the highest quality ('q') from list of candidates. - - Takes a list of supported mime-types and finds the best match for all the - media-ranges listed in header. The value of header must be a string that - conforms to the format of the HTTP Accept: header. The value of 'supported' - is a list of mime-types. The list of supported mime-types should be sorted - in order of increasing desirability, in case of a situation where there is - a tie. - - >>> best_match(['application/xbel+xml', 'text/xml'], - 'text/*;q=0.5,*/*; q=0.1') - 'text/xml' - """ - split_header = _filter_blank(header.split(',')) - parsed_header = [parse_media_range(r) for r in split_header] - weighted_matches = [] - pos = 0 - for mime_type in supported: - weighted_matches.append((fitness_and_quality_parsed(mime_type, - parsed_header), pos, mime_type)) - pos += 1 - weighted_matches.sort() - - return weighted_matches[-1][0][1] and weighted_matches[-1][2] or '' - - -def _filter_blank(i): - for s in i: - if s.strip(): - yield s Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/mimeparse.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/mimeparse.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/model.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/model.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/model.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/model.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,366 +0,0 @@ -#!/usr/bin/python2.4 -# -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Model objects for requests and responses. - -Each API may support one or more serializations, such -as JSON, Atom, etc. The model classes are responsible -for converting between the wire format and the Python -object representation. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import gflags -import logging -import urllib - -from errors import HttpError -from oauth2client.anyjson import simplejson - -FLAGS = gflags.FLAGS - -gflags.DEFINE_boolean('dump_request_response', False, - 'Dump all http server requests and responses. ' - ) - - -def _abstract(): - raise NotImplementedError('You need to override this function') - - -class Model(object): - """Model base class. - - All Model classes should implement this interface. - The Model serializes and de-serializes between a wire - format such as JSON and a Python object representation. - """ - - def request(self, headers, path_params, query_params, body_value): - """Updates outgoing requests with a serialized body. - - Args: - headers: dict, request headers - path_params: dict, parameters that appear in the request path - query_params: dict, parameters that appear in the query - body_value: object, the request body as a Python object, which must be - serializable. - Returns: - A tuple of (headers, path_params, query, body) - - headers: dict, request headers - path_params: dict, parameters that appear in the request path - query: string, query part of the request URI - body: string, the body serialized in the desired wire format. - """ - _abstract() - - def response(self, resp, content): - """Convert the response wire format into a Python object. - - Args: - resp: httplib2.Response, the HTTP response headers and status - content: string, the body of the HTTP response - - Returns: - The body de-serialized as a Python object. - - Raises: - apiclient.errors.HttpError if a non 2xx response is received. - """ - _abstract() - - -class BaseModel(Model): - """Base model class. - - Subclasses should provide implementations for the "serialize" and - "deserialize" methods, as well as values for the following class attributes. - - Attributes: - accept: The value to use for the HTTP Accept header. - content_type: The value to use for the HTTP Content-type header. - no_content_response: The value to return when deserializing a 204 "No - Content" response. - alt_param: The value to supply as the "alt" query parameter for requests. - """ - - accept = None - content_type = None - no_content_response = None - alt_param = None - - def _log_request(self, headers, path_params, query, body): - """Logs debugging information about the request if requested.""" - if FLAGS.dump_request_response: - logging.info('--request-start--') - logging.info('-headers-start-') - for h, v in headers.iteritems(): - logging.info('%s: %s', h, v) - logging.info('-headers-end-') - logging.info('-path-parameters-start-') - for h, v in path_params.iteritems(): - logging.info('%s: %s', h, v) - logging.info('-path-parameters-end-') - logging.info('body: %s', body) - logging.info('query: %s', query) - logging.info('--request-end--') - - def request(self, headers, path_params, query_params, body_value): - """Updates outgoing requests with a serialized body. - - Args: - headers: dict, request headers - path_params: dict, parameters that appear in the request path - query_params: dict, parameters that appear in the query - body_value: object, the request body as a Python object, which must be - serializable by simplejson. - Returns: - A tuple of (headers, path_params, query, body) - - headers: dict, request headers - path_params: dict, parameters that appear in the request path - query: string, query part of the request URI - body: string, the body serialized as JSON - """ - query = self._build_query(query_params) - headers['accept'] = self.accept - headers['accept-encoding'] = 'gzip, deflate' - if 'user-agent' in headers: - headers['user-agent'] += ' ' - else: - headers['user-agent'] = '' - headers['user-agent'] += 'google-api-python-client/1.0' - - if body_value is not None: - headers['content-type'] = self.content_type - body_value = self.serialize(body_value) - self._log_request(headers, path_params, query, body_value) - return (headers, path_params, query, body_value) - - def _build_query(self, params): - """Builds a query string. - - Args: - params: dict, the query parameters - - Returns: - The query parameters properly encoded into an HTTP URI query string. - """ - if self.alt_param is not None: - params.update({'alt': self.alt_param}) - astuples = [] - for key, value in params.iteritems(): - if type(value) == type([]): - for x in value: - x = x.encode('utf-8') - astuples.append((key, x)) - else: - if getattr(value, 'encode', False) and callable(value.encode): - value = value.encode('utf-8') - astuples.append((key, value)) - return '?' + urllib.urlencode(astuples) - - def _log_response(self, resp, content): - """Logs debugging information about the response if requested.""" - if FLAGS.dump_request_response: - logging.info('--response-start--') - for h, v in resp.iteritems(): - logging.info('%s: %s', h, v) - if content: - logging.info(content) - logging.info('--response-end--') - - def response(self, resp, content): - """Convert the response wire format into a Python object. - - Args: - resp: httplib2.Response, the HTTP response headers and status - content: string, the body of the HTTP response - - Returns: - The body de-serialized as a Python object. - - Raises: - apiclient.errors.HttpError if a non 2xx response is received. - """ - self._log_response(resp, content) - # Error handling is TBD, for example, do we retry - # for some operation/error combinations? - if resp.status < 300: - if resp.status == 204: - # A 204: No Content response should be treated differently - # to all the other success states - return self.no_content_response - return self.deserialize(content) - else: - logging.debug('Content from bad request was: %s' % content) - raise HttpError(resp, content) - - def serialize(self, body_value): - """Perform the actual Python object serialization. - - Args: - body_value: object, the request body as a Python object. - - Returns: - string, the body in serialized form. - """ - _abstract() - - def deserialize(self, content): - """Perform the actual deserialization from response string to Python - object. - - Args: - content: string, the body of the HTTP response - - Returns: - The body de-serialized as a Python object. - """ - _abstract() - - -class JsonModel(BaseModel): - """Model class for JSON. - - Serializes and de-serializes between JSON and the Python - object representation of HTTP request and response bodies. - """ - accept = 'application/json' - content_type = 'application/json' - alt_param = 'json' - - def __init__(self, data_wrapper=False): - """Construct a JsonModel. - - Args: - data_wrapper: boolean, wrap requests and responses in a data wrapper - """ - self._data_wrapper = data_wrapper - - def serialize(self, body_value): - if (isinstance(body_value, dict) and 'data' not in body_value and - self._data_wrapper): - body_value = {'data': body_value} - return simplejson.dumps(body_value) - - def deserialize(self, content): - body = simplejson.loads(content) - if isinstance(body, dict) and 'data' in body: - body = body['data'] - return body - - @property - def no_content_response(self): - return {} - - -class RawModel(JsonModel): - """Model class for requests that don't return JSON. - - Serializes and de-serializes between JSON and the Python - object representation of HTTP request, and returns the raw bytes - of the response body. - """ - accept = '*/*' - content_type = 'application/json' - alt_param = None - - def deserialize(self, content): - return content - - @property - def no_content_response(self): - return '' - - -class ProtocolBufferModel(BaseModel): - """Model class for protocol buffers. - - Serializes and de-serializes the binary protocol buffer sent in the HTTP - request and response bodies. - """ - accept = 'application/x-protobuf' - content_type = 'application/x-protobuf' - alt_param = 'proto' - - def __init__(self, protocol_buffer): - """Constructs a ProtocolBufferModel. - - The serialzed protocol buffer returned in an HTTP response will be - de-serialized using the given protocol buffer class. - - Args: - protocol_buffer: The protocol buffer class used to de-serialize a - response from the API. - """ - self._protocol_buffer = protocol_buffer - - def serialize(self, body_value): - return body_value.SerializeToString() - - def deserialize(self, content): - return self._protocol_buffer.FromString(content) - - @property - def no_content_response(self): - return self._protocol_buffer() - - -def makepatch(original, modified): - """Create a patch object. - - Some methods support PATCH, an efficient way to send updates to a resource. - This method allows the easy construction of patch bodies by looking at the - differences between a resource before and after it was modified. - - Args: - original: object, the original deserialized resource - modified: object, the modified deserialized resource - Returns: - An object that contains only the changes from original to modified, in a - form suitable to pass to a PATCH method. - - Example usage: - item = service.activities().get(postid=postid, userid=userid).execute() - original = copy.deepcopy(item) - item['object']['content'] = 'This is updated.' - service.activities.patch(postid=postid, userid=userid, - body=makepatch(original, item)).execute() - """ - patch = {} - for key, original_value in original.iteritems(): - modified_value = modified.get(key, None) - if modified_value is None: - # Use None to signal that the element is deleted - patch[key] = None - elif original_value != modified_value: - if type(original_value) == type({}): - # Recursively descend objects - patch[key] = makepatch(original_value, modified_value) - else: - # In the case of simple types or arrays we just replace - patch[key] = modified_value - else: - # Don't add anything to patch if there's no change - pass - for key in modified: - if key not in original: - patch[key] = modified[key] - - return patch Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/model.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/model.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/oauth.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/oauth.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/oauth.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/oauth.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,443 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for OAuth. - -Utilities for making it easier to work with OAuth. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - - -import copy -import httplib2 -import logging -import oauth2 as oauth -import urllib -import urlparse - -from oauth2client.anyjson import simplejson -from oauth2client.client import Credentials -from oauth2client.client import Flow -from oauth2client.client import Storage - -try: - from urlparse import parse_qsl -except ImportError: - from cgi import parse_qsl - - -class Error(Exception): - """Base error for this module.""" - pass - - -class RequestError(Error): - """Error occurred during request.""" - pass - - -class MissingParameter(Error): - pass - - -class CredentialsInvalidError(Error): - pass - - -def _abstract(): - raise NotImplementedError('You need to override this function') - - -def _oauth_uri(name, discovery, params): - """Look up the OAuth URI from the discovery - document and add query parameters based on - params. - - name - The name of the OAuth URI to lookup, one - of 'request', 'access', or 'authorize'. - discovery - Portion of discovery document the describes - the OAuth endpoints. - params - Dictionary that is used to form the query parameters - for the specified URI. - """ - if name not in ['request', 'access', 'authorize']: - raise KeyError(name) - keys = discovery[name]['parameters'].keys() - query = {} - for key in keys: - if key in params: - query[key] = params[key] - return discovery[name]['url'] + '?' + urllib.urlencode(query) - - - -class OAuthCredentials(Credentials): - """Credentials object for OAuth 1.0a - """ - - def __init__(self, consumer, token, user_agent): - """ - consumer - An instance of oauth.Consumer. - token - An instance of oauth.Token constructed with - the access token and secret. - user_agent - The HTTP User-Agent to provide for this application. - """ - self.consumer = consumer - self.token = token - self.user_agent = user_agent - self.store = None - - # True if the credentials have been revoked - self._invalid = False - - @property - def invalid(self): - """True if the credentials are invalid, such as being revoked.""" - return getattr(self, "_invalid", False) - - def set_store(self, store): - """Set the storage for the credential. - - Args: - store: callable, a callable that when passed a Credential - will store the credential back to where it came from. - This is needed to store the latest access_token if it - has been revoked. - """ - self.store = store - - def __getstate__(self): - """Trim the state down to something that can be pickled.""" - d = copy.copy(self.__dict__) - del d['store'] - return d - - def __setstate__(self, state): - """Reconstitute the state of the object from being pickled.""" - self.__dict__.update(state) - self.store = None - - def authorize(self, http): - """Authorize an httplib2.Http instance with these Credentials - - Args: - http - An instance of httplib2.Http - or something that acts like it. - - Returns: - A modified instance of http that was passed in. - - Example: - - h = httplib2.Http() - h = credentials.authorize(h) - - You can't create a new OAuth - subclass of httplib2.Authenication because - it never gets passed the absolute URI, which is - needed for signing. So instead we have to overload - 'request' with a closure that adds in the - Authorization header and then calls the original version - of 'request()'. - """ - request_orig = http.request - signer = oauth.SignatureMethod_HMAC_SHA1() - - # The closure that will replace 'httplib2.Http.request'. - def new_request(uri, method='GET', body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, - connection_type=None): - """Modify the request headers to add the appropriate - Authorization header.""" - response_code = 302 - http.follow_redirects = False - while response_code in [301, 302]: - req = oauth.Request.from_consumer_and_token( - self.consumer, self.token, http_method=method, http_url=uri) - req.sign_request(signer, self.consumer, self.token) - if headers is None: - headers = {} - headers.update(req.to_header()) - if 'user-agent' in headers: - headers['user-agent'] = self.user_agent + ' ' + headers['user-agent'] - else: - headers['user-agent'] = self.user_agent - - resp, content = request_orig(uri, method, body, headers, - redirections, connection_type) - response_code = resp.status - if response_code in [301, 302]: - uri = resp['location'] - - # Update the stored credential if it becomes invalid. - if response_code == 401: - logging.info('Access token no longer valid: %s' % content) - self._invalid = True - if self.store is not None: - self.store(self) - raise CredentialsInvalidError("Credentials are no longer valid.") - - return resp, content - - http.request = new_request - return http - - -class TwoLeggedOAuthCredentials(Credentials): - """Two Legged Credentials object for OAuth 1.0a. - - The Two Legged object is created directly, not from a flow. Once you - authorize and httplib2.Http instance you can change the requestor and that - change will propogate to the authorized httplib2.Http instance. For example: - - http = httplib2.Http() - http = credentials.authorize(http) - - credentials.requestor = 'foo@example.info' - http.request(...) - credentials.requestor = 'bar@example.info' - http.request(...) - """ - - def __init__(self, consumer_key, consumer_secret, user_agent): - """ - Args: - consumer_key: string, An OAuth 1.0 consumer key - consumer_secret: string, An OAuth 1.0 consumer secret - user_agent: string, The HTTP User-Agent to provide for this application. - """ - self.consumer = oauth.Consumer(consumer_key, consumer_secret) - self.user_agent = user_agent - self.store = None - - # email address of the user to act on the behalf of. - self._requestor = None - - @property - def invalid(self): - """True if the credentials are invalid, such as being revoked. - - Always returns False for Two Legged Credentials. - """ - return False - - def getrequestor(self): - return self._requestor - - def setrequestor(self, email): - self._requestor = email - - requestor = property(getrequestor, setrequestor, None, - 'The email address of the user to act on behalf of') - - def set_store(self, store): - """Set the storage for the credential. - - Args: - store: callable, a callable that when passed a Credential - will store the credential back to where it came from. - This is needed to store the latest access_token if it - has been revoked. - """ - self.store = store - - def __getstate__(self): - """Trim the state down to something that can be pickled.""" - d = copy.copy(self.__dict__) - del d['store'] - return d - - def __setstate__(self, state): - """Reconstitute the state of the object from being pickled.""" - self.__dict__.update(state) - self.store = None - - def authorize(self, http): - """Authorize an httplib2.Http instance with these Credentials - - Args: - http - An instance of httplib2.Http - or something that acts like it. - - Returns: - A modified instance of http that was passed in. - - Example: - - h = httplib2.Http() - h = credentials.authorize(h) - - You can't create a new OAuth - subclass of httplib2.Authenication because - it never gets passed the absolute URI, which is - needed for signing. So instead we have to overload - 'request' with a closure that adds in the - Authorization header and then calls the original version - of 'request()'. - """ - request_orig = http.request - signer = oauth.SignatureMethod_HMAC_SHA1() - - # The closure that will replace 'httplib2.Http.request'. - def new_request(uri, method='GET', body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, - connection_type=None): - """Modify the request headers to add the appropriate - Authorization header.""" - response_code = 302 - http.follow_redirects = False - while response_code in [301, 302]: - # add in xoauth_requestor_id=self._requestor to the uri - if self._requestor is None: - raise MissingParameter( - 'Requestor must be set before using TwoLeggedOAuthCredentials') - parsed = list(urlparse.urlparse(uri)) - q = parse_qsl(parsed[4]) - q.append(('xoauth_requestor_id', self._requestor)) - parsed[4] = urllib.urlencode(q) - uri = urlparse.urlunparse(parsed) - - req = oauth.Request.from_consumer_and_token( - self.consumer, None, http_method=method, http_url=uri) - req.sign_request(signer, self.consumer, None) - if headers is None: - headers = {} - headers.update(req.to_header()) - if 'user-agent' in headers: - headers['user-agent'] = self.user_agent + ' ' + headers['user-agent'] - else: - headers['user-agent'] = self.user_agent - resp, content = request_orig(uri, method, body, headers, - redirections, connection_type) - response_code = resp.status - if response_code in [301, 302]: - uri = resp['location'] - - if response_code == 401: - logging.info('Access token no longer valid: %s' % content) - # Do not store the invalid state of the Credentials because - # being 2LO they could be reinstated in the future. - raise CredentialsInvalidError("Credentials are invalid.") - - return resp, content - - http.request = new_request - return http - - -class FlowThreeLegged(Flow): - """Does the Three Legged Dance for OAuth 1.0a. - """ - - def __init__(self, discovery, consumer_key, consumer_secret, user_agent, - **kwargs): - """ - discovery - Section of the API discovery document that describes - the OAuth endpoints. - consumer_key - OAuth consumer key - consumer_secret - OAuth consumer secret - user_agent - The HTTP User-Agent that identifies the application. - **kwargs - The keyword arguments are all optional and required - parameters for the OAuth calls. - """ - self.discovery = discovery - self.consumer_key = consumer_key - self.consumer_secret = consumer_secret - self.user_agent = user_agent - self.params = kwargs - self.request_token = {} - required = {} - for uriinfo in discovery.itervalues(): - for name, value in uriinfo['parameters'].iteritems(): - if value['required'] and not name.startswith('oauth_'): - required[name] = 1 - for key in required.iterkeys(): - if key not in self.params: - raise MissingParameter('Required parameter %s not supplied' % key) - - def step1_get_authorize_url(self, oauth_callback='oob'): - """Returns a URI to redirect to the provider. - - oauth_callback - Either the string 'oob' for a non-web-based application, - or a URI that handles the callback from the authorization - server. - - If oauth_callback is 'oob' then pass in the - generated verification code to step2_exchange, - otherwise pass in the query parameters received - at the callback uri to step2_exchange. - """ - consumer = oauth.Consumer(self.consumer_key, self.consumer_secret) - client = oauth.Client(consumer) - - headers = { - 'user-agent': self.user_agent, - 'content-type': 'application/x-www-form-urlencoded' - } - body = urllib.urlencode({'oauth_callback': oauth_callback}) - uri = _oauth_uri('request', self.discovery, self.params) - - resp, content = client.request(uri, 'POST', headers=headers, - body=body) - if resp['status'] != '200': - logging.error('Failed to retrieve temporary authorization: %s', content) - raise RequestError('Invalid response %s.' % resp['status']) - - self.request_token = dict(parse_qsl(content)) - - auth_params = copy.copy(self.params) - auth_params['oauth_token'] = self.request_token['oauth_token'] - - return _oauth_uri('authorize', self.discovery, auth_params) - - def step2_exchange(self, verifier): - """Exhanges an authorized request token - for OAuthCredentials. - - Args: - verifier: string, dict - either the verifier token, or a dictionary - of the query parameters to the callback, which contains - the oauth_verifier. - Returns: - The Credentials object. - """ - - if not (isinstance(verifier, str) or isinstance(verifier, unicode)): - verifier = verifier['oauth_verifier'] - - token = oauth.Token( - self.request_token['oauth_token'], - self.request_token['oauth_token_secret']) - token.set_verifier(verifier) - consumer = oauth.Consumer(self.consumer_key, self.consumer_secret) - client = oauth.Client(consumer, token) - - headers = { - 'user-agent': self.user_agent, - 'content-type': 'application/x-www-form-urlencoded' - } - - uri = _oauth_uri('access', self.discovery, self.params) - resp, content = client.request(uri, 'POST', headers=headers) - if resp['status'] != '200': - logging.error('Failed to retrieve access token: %s', content) - raise RequestError('Invalid response %s.' % resp['status']) - - oauth_params = dict(parse_qsl(content)) - token = oauth.Token( - oauth_params['oauth_token'], - oauth_params['oauth_token_secret']) - - return OAuthCredentials(consumer, token, self.user_agent) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/apiclient/schema.py google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/schema.py --- google-tasks-indicator-0.0.3.2~quantal/src/apiclient/schema.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/schema.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,303 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Schema processing for discovery based APIs - -Schemas holds an APIs discovery schemas. It can return those schema as -deserialized JSON objects, or pretty print them as prototype objects that -conform to the schema. - -For example, given the schema: - - schema = \"\"\"{ - "Foo": { - "type": "object", - "properties": { - "etag": { - "type": "string", - "description": "ETag of the collection." - }, - "kind": { - "type": "string", - "description": "Type of the collection ('calendar#acl').", - "default": "calendar#acl" - }, - "nextPageToken": { - "type": "string", - "description": "Token used to access the next - page of this result. Omitted if no further results are available." - } - } - } - }\"\"\" - - s = Schemas(schema) - print s.prettyPrintByName('Foo') - - Produces the following output: - - { - "nextPageToken": "A String", # Token used to access the - # next page of this result. Omitted if no further results are available. - "kind": "A String", # Type of the collection ('calendar#acl'). - "etag": "A String", # ETag of the collection. - }, - -The constructor takes a discovery document in which to look up named schema. -""" - -# TODO(jcgregorio) support format, enum, minimum, maximum - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import copy -from oauth2client.anyjson import simplejson - - -class Schemas(object): - """Schemas for an API.""" - - def __init__(self, discovery): - """Constructor. - - Args: - discovery: object, Deserialized discovery document from which we pull - out the named schema. - """ - self.schemas = discovery.get('schemas', {}) - - # Cache of pretty printed schemas. - self.pretty = {} - - def _prettyPrintByName(self, name, seen=None, dent=0): - """Get pretty printed object prototype from the schema name. - - Args: - name: string, Name of schema in the discovery document. - seen: list of string, Names of schema already seen. Used to handle - recursive definitions. - - Returns: - string, A string that contains a prototype object with - comments that conforms to the given schema. - """ - if seen is None: - seen = [] - - if name in seen: - # Do not fall into an infinite loop over recursive definitions. - return '# Object with schema name: %s' % name - seen.append(name) - - if name not in self.pretty: - self.pretty[name] = _SchemaToStruct(self.schemas[name], - seen, dent).to_str(self._prettyPrintByName) - - seen.pop() - - return self.pretty[name] - - def prettyPrintByName(self, name): - """Get pretty printed object prototype from the schema name. - - Args: - name: string, Name of schema in the discovery document. - - Returns: - string, A string that contains a prototype object with - comments that conforms to the given schema. - """ - # Return with trailing comma and newline removed. - return self._prettyPrintByName(name, seen=[], dent=1)[:-2] - - def _prettyPrintSchema(self, schema, seen=None, dent=0): - """Get pretty printed object prototype of schema. - - Args: - schema: object, Parsed JSON schema. - seen: list of string, Names of schema already seen. Used to handle - recursive definitions. - - Returns: - string, A string that contains a prototype object with - comments that conforms to the given schema. - """ - if seen is None: - seen = [] - - return _SchemaToStruct(schema, seen, dent).to_str(self._prettyPrintByName) - - def prettyPrintSchema(self, schema): - """Get pretty printed object prototype of schema. - - Args: - schema: object, Parsed JSON schema. - - Returns: - string, A string that contains a prototype object with - comments that conforms to the given schema. - """ - # Return with trailing comma and newline removed. - return self._prettyPrintSchema(schema, dent=1)[:-2] - - def get(self, name): - """Get deserialized JSON schema from the schema name. - - Args: - name: string, Schema name. - """ - return self.schemas[name] - - -class _SchemaToStruct(object): - """Convert schema to a prototype object.""" - - def __init__(self, schema, seen, dent=0): - """Constructor. - - Args: - schema: object, Parsed JSON schema. - seen: list, List of names of schema already seen while parsing. Used to - handle recursive definitions. - dent: int, Initial indentation depth. - """ - # The result of this parsing kept as list of strings. - self.value = [] - - # The final value of the parsing. - self.string = None - - # The parsed JSON schema. - self.schema = schema - - # Indentation level. - self.dent = dent - - # Method that when called returns a prototype object for the schema with - # the given name. - self.from_cache = None - - # List of names of schema already seen while parsing. - self.seen = seen - - def emit(self, text): - """Add text as a line to the output. - - Args: - text: string, Text to output. - """ - self.value.extend([" " * self.dent, text, '\n']) - - def emitBegin(self, text): - """Add text to the output, but with no line terminator. - - Args: - text: string, Text to output. - """ - self.value.extend([" " * self.dent, text]) - - def emitEnd(self, text, comment): - """Add text and comment to the output with line terminator. - - Args: - text: string, Text to output. - comment: string, Python comment. - """ - if comment: - divider = '\n' + ' ' * (self.dent + 2) + '# ' - lines = comment.splitlines() - lines = [x.rstrip() for x in lines] - comment = divider.join(lines) - self.value.extend([text, ' # ', comment, '\n']) - else: - self.value.extend([text, '\n']) - - def indent(self): - """Increase indentation level.""" - self.dent += 1 - - def undent(self): - """Decrease indentation level.""" - self.dent -= 1 - - def _to_str_impl(self, schema): - """Prototype object based on the schema, in Python code with comments. - - Args: - schema: object, Parsed JSON schema file. - - Returns: - Prototype object based on the schema, in Python code with comments. - """ - stype = schema.get('type') - if stype == 'object': - self.emitEnd('{', schema.get('description', '')) - self.indent() - for pname, pschema in schema.get('properties', {}).iteritems(): - self.emitBegin('"%s": ' % pname) - self._to_str_impl(pschema) - self.undent() - self.emit('},') - elif '$ref' in schema: - schemaName = schema['$ref'] - description = schema.get('description', '') - s = self.from_cache(schemaName, self.seen) - parts = s.splitlines() - self.emitEnd(parts[0], description) - for line in parts[1:]: - self.emit(line.rstrip()) - elif stype == 'boolean': - value = schema.get('default', 'True or False') - self.emitEnd('%s,' % str(value), schema.get('description', '')) - elif stype == 'string': - value = schema.get('default', 'A String') - self.emitEnd('"%s",' % str(value), schema.get('description', '')) - elif stype == 'integer': - value = schema.get('default', '42') - self.emitEnd('%s,' % str(value), schema.get('description', '')) - elif stype == 'number': - value = schema.get('default', '3.14') - self.emitEnd('%s,' % str(value), schema.get('description', '')) - elif stype == 'null': - self.emitEnd('None,', schema.get('description', '')) - elif stype == 'any': - self.emitEnd('"",', schema.get('description', '')) - elif stype == 'array': - self.emitEnd('[', schema.get('description')) - self.indent() - self.emitBegin('') - self._to_str_impl(schema['items']) - self.undent() - self.emit('],') - else: - self.emit('Unknown type! %s' % stype) - self.emitEnd('', '') - - self.string = ''.join(self.value) - return self.string - - def to_str(self, from_cache): - """Prototype object based on the schema, in Python code with comments. - - Args: - from_cache: callable(name, seen), Callable that retrieves an object - prototype for a schema with the given name. Seen is a list of schema - names already seen as we recursively descend the schema definition. - - Returns: - Prototype object based on the schema, in Python code with comments. - The lines of the code will all be properly indented. - """ - self.from_cache = from_cache - return self._to_str_impl(self.schema) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/apiclient/schema.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/apiclient/schema.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/comboboxcalendar.py google-tasks-indicator-0.0.5.1.quantal.1/src/comboboxcalendar.py --- google-tasks-indicator-0.0.3.2~quantal/src/comboboxcalendar.py 2012-03-31 08:55:14.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/comboboxcalendar.py 2012-12-07 18:25:56.000000000 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python # -*- coding: iso-8859-15 -*- # __author__='atareao' @@ -112,10 +112,6 @@ if type(value) is datetime.datetime: value = datetime.date(value.year,value.month,value.day) self.set_date(value) - if type(value) is str or type(value) is unicode: - value = datetime.datetime.strptime(value,'%Y-%m-%dT%H:%M:%S.%fZ') - value = datetime.date(value.year,value.month,value.day) - self.set_date(value) def on_select(self,widget): if not self.month_changed: diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/comboboxlist.py google-tasks-indicator-0.0.5.1.quantal.1/src/comboboxlist.py --- google-tasks-indicator-0.0.3.2~quantal/src/comboboxlist.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/comboboxlist.py 2012-12-07 18:25:56.000000000 +0000 @@ -0,0 +1,113 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +__author__='atareao' +__date__ ='$19/02/2012$' +# +# +# Copyright (C) 2011,2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# +from gi.repository import Gtk + +class ComboBoxList(Gtk.HBox): + def __init__(self, window, index=0, values = [], height = 150): + Gtk.HBox.__init__(self) + self._window = window + self.entry = Gtk.Entry() + self.entry.set_editable(False) + self.button = Gtk.Button() + self.button.add(Gtk.Arrow.new(Gtk.ArrowType.DOWN, Gtk.ShadowType.IN)) + self.button.connect('clicked', self.on_button) + self.pack_start(self.entry, 0, 0, 0) + self.pack_start(self.button, 0, 0, 0) + self.index = index + self.values = values + self.height = height + + def create_window(self): + self.dialog = Gtk.Dialog(None, None, Gtk.DialogFlags.MODAL) + self.dialog.set_decorated(False) + # + scrolledwindow = Gtk.ScrolledWindow() + scrolledwindow.set_can_focus(False) + scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_OUT) + self.dialog.vbox.pack_start(scrolledwindow, Gtk.AttachOptions.SHRINK, Gtk.AttachOptions.SHRINK,0) + # + self.store = Gtk.ListStore(str) + for value in self.values: + self.store.append([value]) + self.tree = Gtk.TreeView(self.store) + self.tree.set_headers_visible(False) + self.tree.set_can_focus(False) + renderer = Gtk.CellRendererText() + column = Gtk.TreeViewColumn(title=None,cell_renderer=renderer, text=0) + self.tree.append_column(column) + # + scrolledwindow.add(self.tree) + self.tree.connect('focus-out-event',self.on_focus_out) + self.dialog.connect('focus-out-event',self.on_focus_out) + self.tree.connect('cursor-changed',self.on_cursor_changed) + self.dialog.show_all() + + def set_sensitive(self, is_sensistive): + self.entry.set_sensitive(is_sensistive) + self.button.set_sensitive(is_sensistive) + + def set_editable(self, is_editable): + self.entry.set_editable(is_editable) + self.button.set_editable(is_editable) + + def set_height(height=150): + self.height=height + + def on_button(self, button): + win_position = self._window.get_position() + x_win = win_position[0] + self.entry.get_allocation().x + 3 + y_win = win_position[1] + self.entry.get_allocation().y + 2*self.entry.get_allocation().height + 3 + # + self.create_window() + # + width = self.button.get_allocation().x - self.entry.get_allocation().x + self.dialog.set_size_request(width,self.height) + self.dialog.move(x_win, y_win) + self.dialog.grab_focus() + self.set_index(self.index) + self.dialog.run() + self.dialog.hide() + + def on_focus_out(self,widget,event): + self.dialog.hide() + + def set_index(self,index): + self.index = index + self.tree.set_cursor(index) + + def get_index(self): + return self.index + + def get_selected_value(self): + return self.entry.get_text() + + def on_cursor_changed(self,widget): + store,iter = self.tree.get_selection().get_selected() + self.entry.set_text(store.get_value(iter,0)) + self.index = store.get_path(iter) + self.dialog.hide() + diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/comun.py google-tasks-indicator-0.0.5.1.quantal.1/src/comun.py --- google-tasks-indicator-0.0.3.2~quantal/src/comun.py 2012-04-16 09:47:59.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/comun.py 2013-01-19 06:05:13.000000000 +0000 @@ -1,5 +1,5 @@ -#! /usr/bin/python -# -*- coding: iso-8859-1 -*- +#!/usr/bin/python +# -*- coding: utf-8 -*- # # # com.py @@ -27,7 +27,7 @@ __copyright__ = 'Copyright (c) 2012 Lorenzo Carbonell' __license__ = 'GPLV3' __url__ = 'http://www.atareao.es' -__version__ = '0.0.3.2' +__version__ = '0.0.5.1.quantal.1' import os @@ -42,23 +42,28 @@ VERSION = __version__ APP = 'google-tasks-indicator' APPCONF = APP + '.conf' +APPDATA = APP + '.data' APPNAME = 'Google-Tasks-Indicator' - +CONFIG_DIR = os.path.join(os.path.expanduser('~'),'.config') +CONFIG_APP_DIR = os.path.join(CONFIG_DIR, APP) +CONFIG_FILE = os.path.join(CONFIG_APP_DIR, APPCONF) +DATA_FILE = os.path.join(CONFIG_APP_DIR, APPDATA) +BACKUP_FILE = os.path.join(CONFIG_APP_DIR, 'backup') +TOKEN_FILE = os.path.join(CONFIG_APP_DIR, 'token') +if not os.path.exists(CONFIG_APP_DIR): + os.makedirs(CONFIG_APP_DIR) # check if running from source if is_package(): ROOTDIR = '/usr/share/' LANGDIR = os.path.join(ROOTDIR, 'locale-langpack') APPDIR = os.path.join(ROOTDIR, APP) ICONDIR = os.path.join(APPDIR, 'icons') - ICON = '/usr/share/pixmaps/google-tasks-indicator.svg' + SOCIALDIR = os.path.join(APPDIR, 'social') else: VERSION = VERSION + '-src' ROOTDIR = os.path.split(os.path.dirname(__file__))[0] LANGDIR = os.path.join(ROOTDIR, 'template1') APPDIR = os.path.join(ROOTDIR, APP) ICONDIR = os.path.join(ROOTDIR, 'data/icons') - ICON = os.path.join(ICONDIR,'google-tasks-indicator.svg') -CONFIG_DIR = os.path.join(os.path.expanduser('~'),'.config') -CONFIG_APP_DIR = os.path.join(CONFIG_DIR, APP) -CONFIG_FILE = os.path.join(CONFIG_APP_DIR, APPCONF) -COOKIE_FILE = os.path.join(CONFIG_APP_DIR, 'oauth2.dat') + SOCIALDIR = os.path.join(ROOTDIR, 'data/social') +ICON = os.path.join(ICONDIR,'google-tasks-indicator.svg') diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/configurator.py google-tasks-indicator-0.0.5.1.quantal.1/src/configurator.py --- google-tasks-indicator-0.0.3.2~quantal/src/configurator.py 2012-03-14 20:14:16.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/configurator.py 2012-12-09 09:28:09.000000000 +0000 @@ -1,5 +1,5 @@ -#! /usr/bin/python -# -*- coding: iso-8859-1 -*- +#!/usr/bin/python +# -*- coding: utf-8 -*- # __author__='atareao' __date__ ='$19/02/2012' @@ -24,81 +24,57 @@ # # -import ConfigParser -import comun +import codecs import os +import json + +import comun -DEFAULTS = { - 'tasklist_id':'@default', - 'theme':'light' +PARAMS = { 'first-time':True, + 'tasklist_id':None, + 'theme':'light', + 'local':2, + 'external':2, + 'both':2 } class Configuration(object): - def __init__(self): - self.config = ConfigParser.RawConfigParser() - self.conf = DEFAULTS - if not os.path.exists(comun.CONFIG_FILE): - self.create() - self.save() + self.params = PARAMS self.read() - ''' - #################################################################### - Config Functions - #################################################################### - ''' - - def _get(self,key): + + def get(self,key): try: - value = self.config.get('Configuration',key) - except ConfigParser.NoOptionError: - value = DEFAULTS[key] - if value == 'None': - value = None - return value + return self.params[key] + except KeyError: + self.params[key] = PARAMS[key] + return self.params[key] + def has(self,key): + return (key in self.params.keys()) - def set(self, key, value): - if key in self.conf.keys(): - self.conf[key] = value + def set(self,key,value): + self.params[key] = value - def get(self,key): - if key in self.conf.keys(): - return self.conf[key] - return None - - ''' - #################################################################### - Operations - #################################################################### - ''' - def read(self): - self.config.read(comun.CONFIG_FILE) - for key in self.conf.keys(): - self.conf[key] = self._get(key) - - - def create(self): - if not self.config.has_section('Configuration'): - self.config.add_section('Configuration') - self.set_defaults() - - def set_defaults(self): - self.conf = {} - for key in DEFAULTS.keys(): - self.conf[key] = DEFAULTS[key] - self.password = '' + def read(self): + try: + f=codecs.open(comun.CONFIG_FILE,'r','utf-8') + except IOError: + self.save() + f=codecs.open(comun.CONFIG_FILE,'r','utf-8') + try: + self.params = json.loads(f.read()) + except ValueError: + self.save() + f.close() def save(self): - for key in self.conf.keys(): - self.config.set('Configuration', key, self.conf[key]) if not os.path.exists(comun.CONFIG_APP_DIR): os.makedirs(comun.CONFIG_APP_DIR) - self.config.write(open(comun.CONFIG_FILE, 'w')) - - + f=codecs.open(comun.CONFIG_FILE,'w','utf-8') + f.write(json.dumps(self.params)) + f.close() + if __name__=='__main__': configuration = Configuration() - #configuration.set('password','armadillo') - #configuration.save() - print '############################################################' - print configuration.get('password') + configuration.read() + print('user %s'%configuration.get('first-time')) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/datamanager.py google-tasks-indicator-0.0.5.1.quantal.1/src/datamanager.py --- google-tasks-indicator-0.0.3.2~quantal/src/datamanager.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/datamanager.py 2012-12-07 18:25:56.000000000 +0000 @@ -0,0 +1,155 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +__author__='atareao' +__date__ ='$19/02/2012' +# +# +# Copyright (C) 2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# + +import codecs +import os +import json +import comun +import uuid + +DATA = { + 'tasklists':[], + 'tasks':[] + } + +TASKLIST = {'id':'', + 'kind':'tasks#taskList', + 'title':'', + 'updated':'', + 'selfLink':'', + 'on-google':False, + } + +TASK = {'id':'', + 'tasklist_id':'', + 'kind':'tasks#task', + 'title':'', + 'notes':'', + 'position':'', + 'status':'needsAction', + 'updated':'', + 'on-google':False, + 'etag':'', + 'selfLink':'' +} +class Task(object): + def __init__(self,tasklist_id): + self.task = TASK.copy() + self.task['id'] = str(uuid.uuid1()) + task['tasklist_id'] = tasklist_id + + def __eq__(self,other): + return (self.task['id'] == other.task['id']) + +class TaskList(object): + def __init__(self): + self.tasklist = TASKLIST.copy() + self.tasklist['id'] = str(uuid.uuid1()) + + def __eq__(self,other): + return (self.tasklist['id'] == other.tasklist['id']) + +class DataManager(object): + def __init__(self): + self.data = DATA.copy() + self.read() + + def create_tasklist(self): + self.data['tasklists'].append(tasklist) + return tasklist + + def create_task(self,tasklist): + task = TASK.copy() + task['id'] = str(uuid.uuid1()) + task['tasklist-id'] = tasklist['id'] + self.data['tasks'].append(task) + + def get_tasklists(self): + return self.data['tasklists'] + + def get_tasks(self): + return self.data['tasks'] + + + def get_tasklist(self,tasklist_id): + for tasklist in self.data['tasklists']: + if tasklist['id'] == tasklist_id: + return tasklist + return None + + def remove_tasklist(self,tasklist_id): + tasklist = self.get_tasklist(tasklist_id) + if tasklist: + self.data['tasklists'].remove(tasklist) + + def get_task(self,task_id): + for task in self.data['tasks']: + if task['id'] == task_id: + return task + return None + + def remove_task(self,task_id): + task = self.get_task(task_id) + if task: + self.data['task'].remove(task) + + + def read(self): + if os.path.exists(comun.DATA_FILE): + try: + f=codecs.open(comun.DATA_FILE,'r','utf-8') + print 'Read' + except IOError, e: + print 'An error:%s'%e + self.save() + f=codecs.open(comun.DATA_FILE,'r','utf-8') + print 'Read' + values_read = f.read() + f.close() + try: + self.data = json.loads(values_read) + except ValueError,e: + print 'An error:%s'%e + self.save() + self.read() + + def save(self): + if not os.path.exists(comun.CONFIG_APP_DIR): + os.makedirs(comun.CONFIG_APP_DIR) + f=codecs.open(comun.DATA_FILE,'w','utf-8') + f.write(json.dumps(self.data)) + f.close() + print 'Saved' + +if __name__=='__main__': + ''' + datamanager = DataManager() + #tasklist = datamanager.create_tasklist('Lista de prueba') + #task = datamanager.create_task('Tarea de prueba',tasklist) + #datamanager.save() + print datamanager.data + ''' + print TaskList().tasklist['id'] diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/google-tasks-indicator.py google-tasks-indicator-0.0.5.1.quantal.1/src/google-tasks-indicator.py --- google-tasks-indicator-0.0.3.2~quantal/src/google-tasks-indicator.py 2012-03-31 17:15:49.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/google-tasks-indicator.py 2013-01-19 05:57:05.000000000 +0000 @@ -1,5 +1,5 @@ -#! /usr/bin/python -# -*- coding: iso-8859-1 -*- +#!/usr/bin/python +# -*- coding: utf-8 -*- # __author__='lorenzo.carbonell.cerezo@gmail.com' __date__ ='$21/02/2012' @@ -40,13 +40,16 @@ import gettext import datetime import webbrowser +import rfc3339 # import comun import googletasksapi from configurator import Configuration from preferences_dialog import Preferences from task_dialog import TaskDialog +from tasklist_dialog import TaskListDialog from show_tasks_dialog import ShowTasksDialog +from show_taskslists_dialog import ShowTasksListsDialog # locale.setlocale(locale.LC_ALL, '') @@ -66,23 +69,41 @@ def __init__(self,note): Gtk.CheckMenuItem.__init__(self) self.note = note - self.get_children()[0].set_use_markup(True) - if 'title' in note.keys(): + #self.get_children()[0].set_use_markup(True) + if 'title' in note.keys() and note['title'] is not None: if len(note['title'])>28: title = note['title'][0:25]+'...' else: title = note['title'] else: title = '' - if 'notes' in note.keys(): + if 'notes' in note.keys() and note['notes'] is not None: self.set_tooltip_text(note['notes']) if note['status'] == 'completed': - self.get_children()[0].set_markup('%s'%title) + self.set_label(title) self.set_active(True) else: - self.get_children()[0].set_markup('%s'%title) + self.set_label(title) self.set_active(False) + def get_note(self): + return self.note + + def set_note(self,note): + self.note = note + if 'status' in note.keys() and note['status'] == 'completed': + self.set_active(True) + else: + self.set_active(False) + if 'title' in note.keys() and note['title'] is not None: + if len(note['title'])>28: + title = note['title'][0:25]+'...' + else: + title = note['title'] + else: + title = '' + self.set_label(title) + def add2menu(menu, text = None, icon = None, conector_event = None, conector_action = None, note = None): if note != None: @@ -111,15 +132,144 @@ class GoogleTasksIndicator(): def __init__(self): if dbus.SessionBus().request_name("es.atareao.google-tasks-indicator") != dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER: - print "application already running" + print("application already running") exit(0) self.indicator = appindicator.Indicator.new('Google-Tasks-Indicator', 'Google-Tasks-Indicator', appindicator.IndicatorCategory.APPLICATION_STATUS) + self.notification = Notify.Notification.new('','', None) + self.tasks = googletasksapi.TaskAlone() + self.tasks.restore() + if self.tasks.tasklists == {}: + tld = TaskListDialog() + if tld.run() == Gtk.ResponseType.ACCEPT: + tld.hide() + self.tasks.create_tasklist(tld.get_title()) + tld.destroy() self.read_preferences() - # - self.gta = googletasksapi.GTAService() - self.events = [] self.set_menu() + self.menu_update() + def on_destroy(self): + self.tasks.backup() + + def sync(self,widget): + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + error = True + while(error): + if gta.do_refresh_authorization() is None: + p = Preferences(self.tasks) + if p.run() == Gtk.ResponseType.ACCEPT: + p.save_preferences() + p.destroy() + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + if (not os.path.exists(comun.TOKEN_FILE)) or (gta.do_refresh_authorization() is None): + md = Gtk.MessageDialog( parent = None, + flags = Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + type = Gtk.MessageType.ERROR, + buttons = Gtk.ButtonsType.OK_CANCEL, + message_format = _('You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n Do you want to authorize?')) + if md.run() == Gtk.ResponseType.CANCEL: + md.destroy() + return + md.destroy() + else: + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + if gta.do_refresh_authorization() is None: + error = False + else: + error = False + ## Options + configuration = Configuration() + option_local = configuration.get('local') + option_external = configuration.get('external') + option_both = configuration.get('both') + ## + google_tasklists = gta.get_tasklists() + + ## From Local to Google ## + google_task_lists_ids = [] + for gtl in google_tasklists.values(): + google_task_lists_ids.append(gtl['id']) + for tasklist in self.tasks.tasklists.values(): + if tasklist['id'] not in google_task_lists_ids: # Tasklist only local + if option_local == 0: # Copy to external + new_tasklist = gta.create_tasklist(tasklist['title']) + if new_tasklist is not None: + for task in tasklist['tasks'].values(): + if 'due' in task.keys() and task['due'] is not None: + due = rfc3339.parse_datetime(str(task['due'])) + else: + due = None + new_task = gta.create_task( tasklist_id = new_tasklist['id'], title = task['title'], notes=task['notes'], iscompleted=task.get_completed(),due=due,data_completed=task['completed']) + new_tasklist['tasks'][new_task['id']] = new_task + self.tasks.remove_tasklist(tasklist) + self.tasks.tasklists[new_tasklist['id']] = new_tasklist + elif option_local == 1: # delete local + self.tasks.remove_tasklist(tasklist) + else: # Tasklist local and external; + if option_both == 0: # Copy to local + gtl = google_tasklists[tasklist['id']] + tasklist['title'] = gtl['title'] + elif option_both == 1: # Copy to external + if gtl['title'] != tasklist['title']: + gta.edit_tasklist(tasklist['id'],tasklist['title']) + ######################################################## + ## Working with tasks + localtasks = tasklist['tasks'] + googletasks = gta.get_tasks(tasklist_id=tasklist['id']) + ### From Local to Google + print(localtasks) + for task in localtasks.values(): + if task['id'] not in googletasks.keys(): + # Task only local + if option_local == 0: + # Copy to external + new_task = gta.create_task( tasklist_id = task['tasklist_id'], title = task['title'], notes=task['notes'], iscompleted=task.get_completed(),due=task['due'],data_completed=task['completed']) + if new_task is not None: + self.tasks.remove_task(task) + self.tasks.tasklists[task['tasklist_id']]['tasks'][new_task['id']] = new_task + elif option_local == 1: + # Delete local + self.tasks.remove_task(task) + else: + #Task local and external + if option_both == 0: + # Copy to local + self.tasks.tasklists[task['tasklist_id']]['tasks'][task['id']] = googletasks[task['id']] + elif option_both ==1: + # Copy to external + task_id = task['id'] + tasklist_id = task['tasklist_id'] + title = task['title'] + notes = task['notes'] + iscompleted = (task['status']=='completed') + due = task['due'] + gta.edit_task(task_id, tasklist_id , title = title, notes = notes, iscompleted = iscompleted, due = due) + ### From Google to Local + for task in googletasks.values(): + if task['id'] not in localtasks.keys(): + #Task only external + if option_external == 0: + # Copy to local + self.tasks.tasklists[task['tasklist_id']]['tasks'][task['id']] = googletasks[task['id']] + elif option_external == 1: + # Delete external + gta.delete_task(task['id'], task['tasklist_id']) + ######################################################## + ## From Google to Local ## + alone_task_lists_ids = [] + for atl in self.tasks.tasklists.values(): + alone_task_lists_ids.append(atl['id']) + for tasklist in google_tasklists.values(): + if tasklist['id'] not in alone_task_lists_ids: # Tasklist only Google + if option_external == 0: # Copy to local + new_tasklist = tasklist + new_tasklist['tasks'] = gta.get_tasks(tasklist_id = tasklist['id']) + self.tasks.tasklists[new_tasklist['id']] = new_tasklist + elif option_external == 1: # Delete external + gta.delete_tasklist(tasklist) + self.tasks.backup() + self.menu_update() + def read_preferences(self): error = True while error: @@ -128,8 +278,8 @@ self.tasklist_id = configuration.get('tasklist_id') self.theme = configuration.get('theme') error = False - except Exception,e: - print e + except Exception as e: + print(e) error = True p = Preferences() if p.run() == Gtk.ResponseType.ACCEPT: @@ -149,11 +299,22 @@ menu = Gtk.Menu() # self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE) + self.menu_tasks = [] + for i in range(0,10): + menu_note = add2menu(menu, text = '', conector_event = 'activate',conector_action = self.menu_check_item, note = googletasksapi.Task()) + menu_note.set_visible(False) + self.menu_tasks.append(menu_note) + #self.menu_tasks.append(add2menu(menu, text = note['title'], conector_event = 'activate',conector_action = self.menu_check_item, note = note)) + add2menu(menu) add2menu(menu, text = _('Add new task'), conector_event = 'activate',conector_action = self.menu_add_new_task) + add2menu(menu, text = _('Add new task list'), conector_event = 'activate',conector_action = self.menu_add_new_tasklist) + add2menu(menu, text = _('Manage tasklists'), conector_event = 'activate',conector_action = self.menu_manage_tasklists) add2menu(menu) add2menu(menu, text = _('Refresh'), conector_event = 'activate',conector_action = self.menu_refresh) add2menu(menu, text = _('Clear completed tasks'), conector_event = 'activate',conector_action = self.menu_clear_completed_tasks) add2menu(menu, text = _('Show all tasks'), conector_event = 'activate',conector_action = self.menu_show_tasks) + add2menu(menu, text = _('Synchronize with Google'), conector_event = 'activate',conector_action = self.sync) + add2menu(menu) add2menu(menu) add2menu(menu, text = _('Preferences'), conector_event = 'activate',conector_action = self.menu_preferences_response) add2menu(menu) @@ -161,13 +322,8 @@ menu_help.set_submenu(self.get_help_menu()) add2menu(menu) add2menu(menu, text = _('Exit'), conector_event = 'activate',conector_action = self.menu_exit_response) - add2menu(menu) - for note in self.gta.get_tasks(tasklist_id = self.tasklist_id)[0:10]: - add2menu(menu, text = note['title'], conector_event = 'activate',conector_action = self.menu_check_item, note = note) menu.show() self.indicator.set_menu(menu) - while Gtk.events_pending(): - Gtk.main_iteration() def get_help_menu(self): @@ -186,68 +342,109 @@ def menu_preferences_response(self,widget): widget.set_sensitive(False) - p = Preferences(self.gta) + p = Preferences(self.tasks) if p.run() == Gtk.ResponseType.ACCEPT: p.save_preferences() p.destroy() self.read_preferences() - self.set_menu() + self.menu_update() widget.set_sensitive(True) def menu_edit_note(self,widget): widget.set_sensitive(False) - annd = NoteDialog(note = widget.note) + note = widget.note + annd = NoteDialog(note = note) if annd.run() == Gtk.ResponseType.ACCEPT: - title = annd.get_title() - notes = annd.get_notes() - completed = annd.is_completed() + atasklist = self.tasks.tasklists[annd.get_tasklist_id()] + note = self.tasks.create_task(self,atasklist,title) + note['notes'] = annd.get_notes() + note.set_completed(annd.is_completed()) due = annd.get_due_date() - self.gta.edit_task(task_id = widget.note['id'], tasklist_id = self.tasklist_id, title = title, notes = notes, iscompleted = completed, due = due) - # - self.set_menu() + if due is not None: + note.set_due(due) + self.menu_update() annd.destroy() - widget.set_active(widget.note['status'] == 'completed') + widget.set_active(widget.get_note()['status'] == 'completed') widget.set_sensitive(True) def menu_check_item(self,widget): completed = not widget.get_active() - widget.note = self.gta.edit_task(task_id = widget.note['id'], tasklist_id = self.tasklist_id, iscompleted = not completed) - widget.set_active(widget.note['status'] == 'completed') + atask = widget.get_note() + if 'notes' in atask.keys(): + notes = atask['notes'] + else: + notes = '' + atask.set_completed(iscompleted = not completed) + #self.tasks.tasklists[atask['tasklist_id']]['tasks'] + widget.set_note(atask) + widget.set_active(atask['status'] == 'completed') + def menu_manage_tasklists(self,widget): + widget.set_sensitive(False) + stld = ShowTasksListsDialog(self.tasks) + stld.run() + stld.destroy() + self.menu_update() + widget.set_sensitive(True) + def menu_add_new_tasklist(self,widget): + widget.set_sensitive(False) + tld = TaskListDialog() + if tld.run() == Gtk.ResponseType.ACCEPT: + tld.hide() + self.tasks.create_tasklist(tld.get_title()) + tld.destroy() + self.menu_update() + widget.set_sensitive(True) def menu_add_new_task(self,widget): widget.set_sensitive(False) - annd = TaskDialog() + annd = TaskDialog(tasks=self.tasks) if annd.run() == Gtk.ResponseType.ACCEPT: - title = annd.get_title() - notes = annd.get_notes() - completed = annd.is_completed() + annd.hide() + tasklist = self.tasks.tasklists[annd.get_tasklist_id()] + atask = self.tasks.create_task(tasklist,annd.get_title()) + atask['notes'] = annd.get_notes() + atask.set_completed(annd.is_completed()) due = annd.get_due_date() - # - self.gta.create_task(tasklist_id = self.tasklist_id, title = title, notes = notes, time = due, iscompleted = completed) - self.set_menu() + if due is not None: + atask.set_due(due) annd.destroy() + self.menu_update() widget.set_sensitive(True) + def menu_update(self): + number_of_tasks = len(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:10]) + if number_of_tasks < 10: + for index,note in enumerate(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:number_of_tasks]): + self.menu_tasks[index].set_note(note) + self.menu_tasks[index].set_visible(True) + for index in range(number_of_tasks,10): + self.menu_tasks[index].set_visible(False) + else: + for index,note in enumerate(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:10]): + self.menu_tasks[index].set_note(note) + self.menu_tasks[index].set_visible(True) + def menu_clear_completed_tasks(self,widget): widget.set_sensitive(False) - self.gta.clear_completed_tasks(tasklist_id = self.tasklist_id) - self.set_menu() + self.tasks.clear_completed_tasks(tasklist_id = self.tasklist_id) + self.menu_update() widget.set_sensitive(True) def menu_refresh(self,widget): widget.set_sensitive(False) - self.set_menu() + self.menu_update() widget.set_sensitive(True) def menu_show_tasks(self,widget): widget.set_sensitive(False) - snd = ShowTasksDialog(self.gta, self.tasklist_id) + snd = ShowTasksDialog(self.tasks, self.tasklist_id) snd.run() snd.destroy() - self.set_menu() + self.menu_update() widget.set_sensitive(True) def menu_exit_response(self,widget): + self.tasks.backup() exit(0) def menu_about_response(self,widget): @@ -282,4 +479,5 @@ Notify.init("google-tasks-indicator") gti=GoogleTasksIndicator() Gtk.main() + print('eo') diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/googletasksapi.py google-tasks-indicator-0.0.5.1.quantal.1/src/googletasksapi.py --- google-tasks-indicator-0.0.3.2~quantal/src/googletasksapi.py 2012-03-31 09:15:47.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/googletasksapi.py 2013-01-19 05:21:51.000000000 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python # -*- coding: iso-8859-1 -*- # # @@ -22,6 +22,17 @@ # # # +from services import GoogleService +from logindialog import LoginDialog +from urllib.parse import urlencode, quote +import os +import json +import io +import comun +import datetime +import time +import uuid +import rfc3339 ''' Dependencies: @@ -29,175 +40,551 @@ ''' +OAUTH2_URL = 'https://accounts.google.com/o/oauth2/' +AUTH_URL = 'https://accounts.google.com/o/oauth2/auth' +TOKEN_URL = 'https://accounts.google.com/o/oauth2/token' +REDIRECT_URI = 'urn:ietf:wg:oauth:2.0:oob' +REDIRECT_URI = 'http://localhost' +APIKEY = 'AIzaSyDZjnvnk8IBZMUvleSSfGWNnktdKLiKlL0' +CLIENT_ID='197445608333-fd998ofp2ivpj090oputel25imtp7ptk.apps.googleusercontent.com' +CLIENT_SECRET='5So18nKZnWZsKGzOG0pmJUWh' +SCOPE='https://www.googleapis.com/auth/tasks' + +class Task(dict): + def __init__(self,entry=None): + thetime = datetime.datetime.now() + position = str(int(time.mktime(thetime.timetuple()))) + if len(position)<20: + position = '0'*(20-len(position))+position + self['kind'] = "tasks#task" + self['id'] = str(uuid.uuid4()) + self['title'] = None + self['updated'] = rfc3339.rfc3339(thetime) + self['selfLink'] = None + self['parent'] = None + self['position'] = position + self['notes'] = None + self['status'] = 'needsAction' + self['due'] = None + self['completed'] = None + self['deleted'] = False + self['hidden'] = False + self['links'] = [] + self['tasklist_id'] = None + self['sync'] = False + self.set_from_entry(entry) + + def set_due(self,due): + self['due'] = rfc3339.rfc3339(due) + def get_completed(self): + return (self['status'] == 'completed') + def set_completed(self,iscompleted = True): + if iscompleted: + self['status'] = 'completed' + self['completed'] = rfc3339.rfc3339(datetime.datetime.now()) + else: + self['status'] = 'needsAction' + self['completed'] = None + + def set_from_entry(self,entry): + if entry is not None: + self.update(entry) + + def __str__(self): + ans = '' + for key in self.keys(): + ans += '%s: %s\n'%(key,self[key]) + return ans + def get_position(self): + if 'position' in self.keys(): + return(self['position']) + return None + + def __eq__(self,other): + for key in self.keys(): + if key is not None and other is not None and key in other.keys(): + if self[key] != other[key]: + return False + else: + return False + return True -import gflags -import httplib2 - -from apiclient.discovery import build -from oauth2client.file import Storage -from oauth2client.client import OAuth2WebServerFlow -from oauth2client.tools import run + def __ne__(self,other): + return not self.__eq__(other) -import datetime -import comun -FLAGS = gflags.FLAGS + def __lt__(self,other): + return self.get_position() < other.get_position() -# Set up a Flow object to be used if we need to authenticate. This -# sample uses OAuth 2.0, and we set up the OAuth2WebServerFlow with -# the information it needs to authenticate. Note that it is called -# the Web Server Flow, but it can also handle the flow for native -# applications -# The client_id and client_secret are copied from the API Access tab on -# the Google APIs Console - -FLOW = OAuth2WebServerFlow( - client_id='197445608333.apps.googleusercontent.com', - client_secret='DwhP0pHLYhjtVEJ5nIMryp-n', - scope='https://www.googleapis.com/auth/tasks', - user_agent='Google-Tasks-Indicator/0.0.1.0') + def __le__(self,other): + return self.get_position() <= other.get_position() + + def __gt__(self,other): + return self.get_position() > other.get_position() + + def __ge__(self,other): + return self.get_position() >= other.get_position() + +class TaskList(dict): + def __init__(self,entry=None): + self['kind'] = "tasks#taskList" + self['id'] = str(uuid.uuid4()) + self['title'] = None + self['updated'] = rfc3339.rfc3339(datetime.datetime.now()) + self['selfLink'] = None + self['tasks'] = {} + self.set_from_entry(entry) + + def set_from_entry(self,entry): + if entry is not None: + self['kind'] = entry['kind'] if 'kind' in entry.keys() else None + self['id'] = entry['id'] if 'id' in entry.keys() else None + self['title'] = entry['title'] if 'title' in entry.keys() else None + self['updated'] = entry['updated'] if 'updated' in entry.keys() else None + self['selfLink'] = entry['selfLink'] if 'selfLink' in entry.keys() else None + self['tasks'] = {} + print('aqui') + if 'tasks' in entry.keys(): + for atask_value in entry['tasks'].values(): + atask = Task(atask_value) + self['tasks'][atask['id']] = atask + + def set_tasks(self,tasks): + self['tasks'] = tasks + + def __str__(self): + ans = '' + for key in self.keys(): + ans += '%s: %s\n'%(key,self[key]) + return ans -class GTAService(): +class TaskAlone(object): def __init__(self): - # To disable the local server feature, uncomment the following line: - # FLAGS.auth_local_webserver = False + self.tasklists = {} - # If the Credentials don't exist or are invalid, run through the native client - # flow. The Storage object will ensure that if successful the good - # Credentials will get written back to a file. - storage = Storage(comun.COOKIE_FILE) - credentials = storage.get() - if credentials is None or credentials.invalid == True: - credentials = run(FLOW, storage) - - # Create an httplib2.Http object to handle our HTTP requests and authorize it - # with our good Credentials. - http = httplib2.Http() - http = credentials.authorize(http) - - # Build a service object for interacting with the API. Visit - # the Google APIs Console - # to get a developerKey for your own application. - self.service = build(serviceName='tasks', version='v1', http=http,developerKey='AIzaSyDrzTfquQVzNGV9aOA93jMmWC4wB9bd530') + def backup(self): + f = open(comun.BACKUP_FILE,'w') + f.write(json.dumps(self.tasklists, sort_keys = True, indent = 4)) + f.close() - def get_tasklists(self): - tasklists = self.service.tasklists().list().execute() - return tasklists['items'] + def create_tasklist(self,title): + tasklist = TaskList() + tasklist['title'] = title + self.tasklists[tasklist['id']] = tasklist + return tasklist - def get_tasklist(self,tasklist_id): - tasklist = self.service.tasklists().get(tasklist=tasklist_id).execute() + def edit_tasklist(self,tasklist): + self.tasklists[tasklist['id']] = tasklist return tasklist - def create_tasklist(self,title): - tasklist = { - 'title': title + def remove_tasklist(self,tasklist): + del self.tasklists[tasklist['id']] + + def create_task(self,atasklist,title): + atask = Task() + atask['title'] = title + atask['tasklist_id'] = atasklist['id'] + self.tasklists[atasklist['id']]['tasks'][atask['id']] = atask + return atask + + def edit_task(self,task): + self.tasklists[task['tasklist_id']]['tasks'][task['id']] = task + return task + + def remove_task(self,task): + del self.tasklists[task['tasklist_id']]['tasks'][task['id']] + + def move_tasks(self,first_task,last_task): + temporal_position = first_task['position'] + first_task['position'] = last_task['position'] + last_task['position'] = temporal_position + + def move_task_first(self,atask,tasklist_id=None): + tasks = self.get_tasks(tasklist_id) + if len(tasks)>0: + self.move_tasks(atask,tasks[0]) + + def get_tasklists(self): + return self.tasklists.values() + + def get_tasks(self,tasklist_id = None): + tasks = [] + if tasklist_id is None: + for tasklist in self.tasklists.values(): + tasks.extend(tasklist['tasks'].values()) + else: + if tasklist_id in self.tasklists.keys(): + tasks = self.tasklists[tasklist_id]['tasks'].values() + return sorted(tasks) + + def clear_completed_tasks(self,tasklist_id = None): + for task in self.get_tasks(tasklist_id = tasklist_id): + if task['status'] == 'completed': + self.remove_task(task) + + def restore(self): + if os.path.exists(comun.BACKUP_FILE): + f = open(comun.BACKUP_FILE,'r') + data = f.read() + f.close() + midata = json.loads(data) + self.tasklists = {} + for tasklist_value in midata.values(): + atasklist = TaskList(tasklist_value) + self.tasklists[atasklist['id']] = atasklist + else: + self.tasklists = {} + +class GTAService(GoogleService): + def __init__(self,token_file): + GoogleService.__init__(self,auth_url=AUTH_URL,token_url=TOKEN_URL,redirect_uri=REDIRECT_URI,scope=SCOPE,client_id=CLIENT_ID,client_secret=CLIENT_SECRET,token_file=comun.TOKEN_FILE) + self.tasklists = {} + + def read(self): + for atasklist in self._get_tasklists().values(): + atasklist['tasks'] = self._get_tasks(atasklist['id']) + self.tasklists[atasklist['id']] = atasklist + + def backup(self): + f = open(comun.BACKUP_FILE,'w') + f.write(json.dumps(self.tasklists, sort_keys = True, indent = 4)) + f.close() + + def restore(self): + f = open(comun.BACKUP_FILE,'r') + data = f.read() + f.close() + midata = json.loads(data) + self.tasklists = {} + for tasklist_value in midata.values(): + atasklist = TaskList(tasklist_value) + tasks = {} + for task_value in atasklist['tasks'].values(): + atask = Task(task_value) + tasks[atask['id']] = atask + atasklist['tasks'] = tasks + self.tasklists[atasklist['id']] = atasklist + + def __do_request(self,method,url,addheaders=None,data=None,params=None,first=True): + headers ={'Authorization':'OAuth %s'%self.access_token} + if addheaders: + headers.update(addheaders) + print(headers) + if data: + if params: + response = self.session.request(method,url,data=data,headers=headers,params=params) + else: + response = self.session.request(method,url,data=data,headers=headers) + else: + if params: + response = self.session.request(method,url,headers=headers,params=params) + else: + response = self.session.request(method,url,headers=headers) + print(response) + if response.status_code == 200 or response.status_code == 201 or response.status_code == 204: + return response + elif (response.status_code == 401 or response.status_code == 403) and first: + ans = self.do_refresh_authorization() + print(ans) + if ans: + return self.__do_request(method,url,addheaders,data,params,first=False) + return None + + def _get_tasklists(self): + tasklists = {} + params = {'maxResults':1000000} + response = self.__do_request('GET','https://www.googleapis.com/tasks/v1/users/@me/lists',params=params) + if response and response.text: + try: + answer = json.loads(response.text) + if 'items' in answer.keys(): + for item in answer['items']: + atasklist = TaskList(item) + tasklists[atasklist['id']] = atasklist + except: + pass + return tasklists + + def _add_tasklist(self,title): + url = 'https://www.googleapis.com/tasks/v1/users/@me/lists' + data = {'kind': 'tasks#taskList','title':title} + body = json.dumps(data).encode('utf-8') + addheaders={'Content-type':'application/json'} + response = self.__do_request('POST',url,addheaders=addheaders,data = body) + if response and response.text: + try: + ans = json.loads(response.text) + print(ans) + return TaskList(ans) + except Exception as e: + print(e) + return None + def _edit_tasklist(self,tasklist_id, title): + params = {'tasklist':tasklist_id} + url = 'https://www.googleapis.com/tasks/v1/users/@me/lists/%s'%(tasklist_id) + data = { + 'title':title } - result = self.service.tasklists().insert(body=tasklist).execute() - return result + body = json.dumps(data).encode('utf-8') + addheaders={'Content-type':'application/json'} + response = self.__do_request('PATCH',url,addheaders=addheaders,params=params,data = body) + if response and response.text: + try: + atasklist = TaskList(json.loads(response.text)) + except Exception as e: + print(e) + return None + + def _delete_tasklist(self,tasklist): + url = 'https://www.googleapis.com/tasks/v1/users/@me/lists/%s'%(tasklist['id']) + params = {'tasklist':tasklist['id']} + response = self.__do_request('DELETE',url,params = params) + if response and response.text: + try: + return True + except Exception as e: + print(e) + return False + + def _get_tasks(self,tasklist_id = '@default'): + tasks = {} + params = {'tasklist':tasklist_id,'maxResults':1000000} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/tasks'%(tasklist_id) + response = self.__do_request('GET',url,params=params) + if response and response.text: + try: + answer = json.loads(response.text) + if 'items' in answer.keys(): + for item in answer['items']: + atask = Task(item) + atask['tasklist_id'] = tasklist_id + tasks[atask['id']] = atask + except: + pass + return tasks - def update_tasklist(self, tasklist_id, new_title): - tasklist = self.service.tasklists().get(tasklist=tasklist_id).execute() - tasklist['title'] = new_title - result = self.service.tasklists().update(tasklist=tasklist['id'], body=tasklist).execute() - return result - - def delete_tasklist(self,tasklist_id): - result = self.service.tasklists().delete(tasklist=tasklist_id).execute() - return result + def _clear_completed_tasks(self,tasklist_id = '@default'): + params = {'tasklist':tasklist_id} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/clear'%(tasklist_id) + addheaders={'Content-Length':'0'} + response = self.__do_request('POST',url,params=params,addheaders=addheaders) + if response is not None: + try: + return True + except Exception as e: + print(e) + return False - def clear_completed_tasks(self,tasklist_id = '@default'): - return self.service.tasks().clear(tasklist = tasklist_id).execute() + def _delete_task(self,tasklist_id,task_id): + params = {'tasklist':tasklist_id,'task':task_id} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/tasks/%s'%(tasklist_id,task_id) + response = self.__do_request('DELETE',url,params=params) + if response and response.text: + try: + return True + except Exception as e: + print(e) + return False + + + + def _edit_task(self,tasklist_id,task_id, title,notes=None, iscompleted=False, due=None, data_completed=None,deleted=False): + params = {'tasklist':tasklist_id,'task':task_id} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/tasks/%s'%(tasklist_id,task_id) + data = { + 'kind': 'tasks#task', + 'title':title, + 'deleted':deleted + } + if notes is not None: + data['notes'] = notes + if iscompleted: + data['status'] = 'completed' + if data_completed is not None: + data['completed'] = rfc3339.rfc3339(data_completed) + else: + data['completed'] = rfc3339.rfc3339(datetime.datetime.now()) + else: + data['status'] = 'needsAction' + data['completed'] = None + if due is not None: + data['due'] = rfc3339.rfc3339(due) + body = json.dumps(data).encode('utf-8') + addheaders={'Content-type':'application/json'} + response = self.__do_request('PATCH',url,addheaders=addheaders,params=params,data = body) + if response and response.text: + try: + atask = Task(json.loads(response.text)) + atask['tasklist_id'] = tasklist_id + return atask + except Exception as e: + print(e) + return None + def _move_task(self,tasklist_id,task_id,parent_id=None,previous_id=None): + params = {'tasklist':tasklist_id,'task':task_id} + if parent_id is not None: + params['parent'] = parent_id + if previous_id is not None: + params['previous'] = previous_id + addheaders={'Content-Length':'0'} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/tasks/%s/move'%(tasklist_id,task_id) + response = self.__do_request('POST',url,params=params,addheaders=addheaders) + if response and response.text: + try: + atask = Task(json.loads(response.text)) + atask['tasklist_id'] = tasklist_id + return atask + except Exception as e: + print(e) + return None + + def _add_task(self,tasklist_id,title,notes=None, iscompleted=False, due=None, data_completed=None,deleted=False): + params = {'tasklist':tasklist_id} + url = 'https://www.googleapis.com/tasks/v1/lists/%s/tasks'%(tasklist_id) + data = { + 'kind': 'tasks#task', + 'title':title, + 'deleted':deleted + } + if notes is not None: + data['notes'] = notes + if iscompleted: + data['status'] = 'completed' + if data_completed is not None: + data['completed'] = rfc3339.rfc3339(data_completed) + else: + data['completed'] = rfc3339.rfc3339(datetime.datetime.now()) + else: + data['status'] = 'needsAction' + data['completed'] = None + if due is not None: + data['due'] = rfc3339.rfc3339(due) + body = json.dumps(data).encode('utf-8') + addheaders={'Content-type':'application/json'} + response = self.__do_request('POST',url,addheaders=addheaders,params=params,data = body) + if response and response.text: + try: + atask = Task(json.loads(response.text)) + atask['tasklist_id'] = tasklist_id + return atask + except Exception as e: + print(e) + return None + + def get_tasklists(self): + tasklists = self._get_tasklists() + return tasklists + + def create_tasklist(self,title): + return self._add_tasklist(title) + def update_tasklist(self, tasklist): + return self._edit_tasklist(tasklist) + def delete_tasklist(self,tasklist): + return self._delete_tasklist(tasklist) + + def clear_completed_tasks(self,tasklist_id = '@default'): + return self._clear_completed_tasks(tasklist_id = tasklist_id) def get_tasks(self, tasklist_id = '@default'): - tasks = self.service.tasks().list(tasklist=tasklist_id).execute() - if tasks and 'items' in tasks.keys(): - tasks = tasks['items'] + tasks = {} + if tasklist_id is None: + for atasklist in self._get_tasklists().values(): + for task in self._get_tasks(atasklist['id']).values(): + tasks[task['id']] = task else: - tasks = [] + tasks = self._get_tasks(tasklist_id) return tasks - - def get_task(self, task_id, tasklist_id = '@default'): - task = self.service.tasks().get(tasklist = tasklist_id, task = task_id).execute() - return task - def create_task(self, tasklist_id = '@default', title = '', notes = '', time = None, iscompleted = False): - if iscompleted: - status = 'completed' - else: - status = 'needsAction' - if time: - time = time.strftime('%Y-%m-%dT%H:%M:%S.000Z') - task = { - 'title': title, - 'notes': notes, - 'status' : status, - 'due': time - } - else: - task = { - 'title': title, - 'notes': notes, - 'status' : status - } - result = self.service.tasks().insert(tasklist='@default', body=task).execute() - return result + + def create_task(self, tasklist_id = '@default', title = '', notes=None, iscompleted=False, due=None, data_completed=None,deleted=False): + atask = self._add_task(tasklist_id,title,notes=notes, iscompleted=iscompleted, due=due, data_completed=data_completed,deleted=deleted) + return atask def move_task(self, task_id, previous_task_id,tasklist_id = '@default'): - result = self.service.tasks().move(tasklist=tasklist_id, task=task_id, previous=previous_task_id).execute() - return result + return self._move_task(tasklist_id,task_id,previous_id=previous_task_id) def move_task_first(self,task_id, tasklist_id = '@default'): - result = self.service.tasks().move(tasklist=tasklist_id, task=task_id).execute() - return result + return self._move_task(tasklist_id,task_id) + def edit_tasklist(self, tasklist_id, title): + return self._edit_tasklist(tasklist_id,title) - def edit_task(self, task_id, tasklist_id = '@default', title = None, notes = None, iscompleted = None, due = None): - task = self.service.tasks().get(tasklist = tasklist_id, task = task_id).execute() - if not title: - if 'title' in task.keys(): - title = task['title'] - if not notes: - if 'notes' in task.keys(): - notes = task['notes'] - if iscompleted!= None: - if iscompleted == True: - status = 'completed' - else: - status = 'needsAction' - elif 'status' in task.keys(): - status = task['status'] - else: - status = 'needsAction' - if due: - time = due.strftime('%Y-%m-%dT%H:%M:%S.000Z') - task = { - 'id' : task_id, - 'title': title, - 'notes': notes, - 'status' : status, - 'due': time - } - else: - task = { - 'id' : task_id, - 'title': title, - 'notes': notes, - 'status' : status - } - result = self.service.tasks().update(tasklist=tasklist_id, task=task_id, body=task).execute() - return result + def edit_task(self, task_id, tasklist_id = '@default', title = None, notes = None, iscompleted = False, due = None): + return self._edit_task(tasklist_id,task_id,title,notes,iscompleted) - def delete_task(self,task_id, tasklist_id = '@default'): - return self.service.tasks().delete(tasklist=tasklist_id, task=task_id).execute() - + def delete_task(self, task_id, tasklist_id = '@default'): + return self._delete_task(tasklist_id,task_id) if __name__ == '__main__': - gta = GTAService() + ta = TaskAlone() + ta.restore() + print(ta.tasklists) + #tasklist = ta.tasklists['398cecc5-a699-4b4d-94da-5c856244d04c'] + #task = ta.create_task(tasklist,'otra prueba') + ''' + print(ta.tasklists) + tasklist = ta.tasklists['398cecc5-a699-4b4d-94da-5c856244d04c'] + tasklist = ta.create_tasklist('lista de prueba') + print(tasklist) + task = ta.create_task(tasklist,'prueba') + print(task) + print(tasklist) + print(ta.tasklists) + + ''' + ''' + tasklist = ta.create_tasklist('prueba') + print(tasklist) + task = ta.create_task(tasklist,'prueba') + print(task) + print(tasklist) + task['title'] = 'La tarea de la lista' + print(tasklist) + ''' + ta.backup() + ''' + + gta = GTAService(token_file = comun.TOKEN_FILE) + #gc = GoogleCalendar(token_file = comun.TOKEN_FILE) + + print(gta.do_refresh_authorization()) + if gta.access_token is None or gta.refresh_token is None: + authorize_url = gta.get_authorize_url() + print(authorize_url) + ld = LoginDialog(authorize_url) + ld.run() + temporary_token = ld.code + ld.destroy() + print(temporary_token) + print(gta.get_authorization(temporary_token)) + print(gta.get_tasklists()) + #print(gta.create_tasklist('Una lista de ejemplo')) + #print(gta.get_tasks()) + print'#############################################################' + print(gta.clear_completed_tasks('@default')) + print'#############################################################' + atask = (gta.create_task(tasklist_id='MDU4MDg5OTIxODI5ODgyMTE0MTg6MTA2NTc3MDc0Mzow',title='prueba')) + print'#############################################################' + print(atask) + print'#############################################################' + gta.move_task_first(atask['id'],atask['tasklist_id']) + gta.read() + atask = gta.edit_task(atask['id'],atask['tasklist_id'],title='otra prueba') + print(atask) + ''' ''' for tasklist in gta.get_tasklists(): + print '########################################################' print tasklist + for task in gta.get_tasks(tasklist_id = tasklist['id']): + print task + ''' + ''' + for tasklist in gta.get_tasklists(): + print tasklist + #print gta.create_tasklist('desde ubuntu') #print gta.get_tasklist('MDU4MDg5OTIxODI5ODgyMTE0MTg6MDow') print gta.get_tasks() @@ -205,3 +592,4 @@ print '%s -> %s'%(task['title'],task['id']) #print gta.create_task(title = 'prueba2 desde ubuntu',notes = 'primera prueba') gta.move_task_first('MDU4MDg5OTIxODI5ODgyMTE0MTg6MDoy') + ''' diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/googletasksindicator.py google-tasks-indicator-0.0.5.1.quantal.1/src/googletasksindicator.py --- google-tasks-indicator-0.0.3.2~quantal/src/googletasksindicator.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/googletasksindicator.py 2012-12-24 09:21:46.000000000 +0000 @@ -0,0 +1,478 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +__author__='lorenzo.carbonell.cerezo@gmail.com' +__date__ ='$21/02/2012' +# +# Google-Tasks-Indicator +# An indicator for Google Tasks +# +# Copyright (C) 2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# +import os +import gi +gi.require_version('Gtk', '3.0') +from gi.repository import GObject +from gi.repository import AppIndicator3 as appindicator +from gi.repository import Gtk +from gi.repository import GdkPixbuf +from gi.repository import Notify + +import time +import dbus +import locale +import gettext +import datetime +import webbrowser +import rfc3339 +# +import comun +import googletasksapi +from configurator import Configuration +from preferences_dialog import Preferences +from task_dialog import TaskDialog +from tasklist_dialog import TaskListDialog +from show_tasks_dialog import ShowTasksDialog +# + +locale.setlocale(locale.LC_ALL, '') +gettext.bindtextdomain(comun.APP, comun.LANGDIR) +gettext.textdomain(comun.APP) +_ = gettext.gettext + +def internet_on(): + try: + response=urllib2.urlopen('http://google.com',timeout=1) + return True + except: + pass + return False + +class MenuNote(Gtk.CheckMenuItem): + def __init__(self,note): + Gtk.CheckMenuItem.__init__(self) + self.note = note + #self.get_children()[0].set_use_markup(True) + if 'title' in note.keys() and note['title'] is not None: + if len(note['title'])>28: + title = note['title'][0:25]+'...' + else: + title = note['title'] + else: + title = '' + if 'notes' in note.keys() and note['notes'] is not None: + self.set_tooltip_text(note['notes']) + if note['status'] == 'completed': + self.set_label(title) + self.set_active(True) + else: + self.set_label(title) + self.set_active(False) + + def get_note(self): + return self.note + + def set_note(self,note): + self.note = note + if 'status' in note.keys() and note['status'] == 'completed': + self.set_active(True) + else: + self.set_active(False) + if 'title' in note.keys(): + if len(note['title'])>28: + title = note['title'][0:25]+'...' + else: + title = note['title'] + else: + title = '' + self.set_label(title) + + +def add2menu(menu, text = None, icon = None, conector_event = None, conector_action = None, note = None): + if note != None: + menu_item = MenuNote(note) + else: + if text != None: + menu_item = Gtk.ImageMenuItem.new_with_label(text) + if icon: + image = Gtk.Image.new_from_stock(icon, Gtk.IconSize.MENU) + menu_item.set_image(image) + menu_item.set_always_show_image(True) + else: + if icon == None: + menu_item = Gtk.SeparatorMenuItem() + else: + menu_item = Gtk.ImageMenuItem.new_from_stock(icon, None) + menu_item.set_always_show_image(True) + if conector_event != None and conector_action != None: + menu_item.connect(conector_event,conector_action) + menu_item.show() + menu.append(menu_item) + return menu_item + +class GoogleTasksIndicator(): + def __init__(self): + if dbus.SessionBus().request_name("es.atareao.google-tasks-indicator") != dbus.bus.REQUEST_NAME_REPLY_PRIMARY_OWNER: + print("application already running") + exit(0) + self.indicator = appindicator.Indicator.new('Google-Tasks-Indicator', 'Google-Tasks-Indicator', appindicator.IndicatorCategory.APPLICATION_STATUS) + self.notification = Notify.Notification.new('','', None) + self.tasks = googletasksapi.TaskAlone() + self.read_preferences() + self.tasks.restore() + if self.tasklist_id is None and len(self.tasks.tasklists.values())>0: + for item in self.tasks.tasklists.values(): + self.tasklist_id = item['id'] + break + self.create_menu() + self.menu_update() + + def on_destroy(self): + self.tasks.backup() + + def sync(self,widget): + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + error = True + while(error): + if gta.do_refresh_authorization() is None: + p = Preferences(self.tasks) + if p.run() == Gtk.ResponseType.ACCEPT: + p.save_preferences() + p.destroy() + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + if (not os.path.exists(comun.TOKEN_FILE)) or (gta.do_refresh_authorization() is None): + md = Gtk.MessageDialog( parent = None, + flags = Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + type = Gtk.MessageType.ERROR, + buttons = Gtk.ButtonsType.OK_CANCEL, + message_format = _('You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n Do you want to authorize?')) + if md.run() == Gtk.ResponseType.CANCEL: + md.destroy() + return + md.destroy() + else: + gta = googletasksapi.GTAService(token_file = comun.TOKEN_FILE) + if gta.do_refresh_authorization() is None: + error = False + else: + error = False + ## Options + configuration = Configuration() + option_local = configuration.get('local') + option_external = configuration.get('external') + option_both = configuration.get('both') + ## + google_tasklists = gta.get_tasklists() + + ## From Local to Google ## + google_task_lists_ids = [] + for gtl in google_tasklists.values(): + google_task_lists_ids.append(gtl['id']) + for tasklist in self.tasks.tasklists.values(): + if tasklist['id'] not in google_task_lists_ids: # Tasklist only local + if option_local == 0: # Copy to external + new_tasklist = gta.create_tasklist(tasklist['title']) + if new_tasklist is not None: + for task in tasklist['tasks'].values(): + if 'due' in task.keys() and task['due'] is not None: + due = rfc3339.parse_datetime(str(task['due'])) + else: + due = None + new_task = gta.create_task( tasklist_id = new_tasklist['id'], title = task['title'], notes=task['notes'], iscompleted=task.get_completed(),due=due,data_completed=task['completed']) + new_tasklist['tasks'][new_task['id']] = new_task + self.tasks.remove_tasklist(tasklist) + self.tasks.tasklists[new_tasklist['id']] = new_tasklist + elif option_local == 1: # delete local + self.tasks.remove_tasklist(tasklist) + else: # Tasklist local and external; + if option_both == 0: # Copy to local + gtl = google_tasklists[tasklist['id']] + tasklist['title'] = gtl['title'] + elif option_both == 1: # Copy to external + if gtl['title'] != tasklist['title']: + gta.edit_tasklist(tasklist['id'],tasklist['title']) + ######################################################## + ## Working with tasks + localtasks = tasklist['tasks'] + googletasks = gta.get_tasks(tasklist_id=tasklist['id']) + ### From Local to Google + for task in localtasks.values(): + if task['id'] not in googletasks.keys(): + # Task only local + if option_local == 0: + # Copy to external + new_task = gta.create_task( tasklist_id = task['tasklist_id'], title = task['title'], notes=task['notes'], iscompleted=task.get_completed(),due=due,data_completed=task['completed']) + if new_task is not None: + self.tasks.remove_task(task) + self.tasks.tasklists[task['tasklist_id']]['tasks'][new_task['id']] = new_task + elif option_local == 1: + # Delete local + self.tasks.remove_task(task) + else: + #Task local and external + if option_both == 0: + # Copy to local + self.tasks.tasklists[task['tasklist_id']]['tasks'][task['id']] = googletasks[task['id']] + elif option_both ==1: + # Copy to external + task_id = task['id'] + tasklist_id = task['tasklist_id'] + title = task['title'] + notes = task['notes'] + iscompleted = (task['status']=='completed') + due = task['due'] + gta.edit_task(task_id, tasklist_id , title = title, notes = notes, iscompleted = iscompleted, due = due) + ### From Google to Local + for task in googletasks.values(): + if task['id'] not in localtasks.keys(): + #Task only external + if option_external == 0: + # Copy to local + self.tasks.tasklists[task['tasklist_id']]['tasks'][task['id']] = googletasks[task['id']] + elif option_external == 1: + # Delete external + gta.delete_task(task['id'], task['tasklist_id']) + ######################################################## + ## From Google to Local ## + alone_task_lists_ids = [] + for atl in self.tasks.tasklists.values(): + alone_task_lists_ids.append(atl['id']) + for tasklist in google_tasklists.values(): + if tasklist['id'] not in alone_task_lists_ids: # Tasklist only Google + if option_external == 0: # Copy to local + new_tasklist = tasklist + new_tasklist['tasks'] = gta.get_tasks(tasklist_id = tasklist['id']) + self.tasks.tasklists[new_tasklist['id']] = new_tasklist + elif option_external == 1: # Delete external + gta.delete_tasklist(tasklist) + self.tasks.backup() + self.menu_update() + + def read_preferences(self): + configuration = Configuration() + self.tasklist_id = configuration.get('tasklist_id') + self.theme = configuration.get('theme') + + def create_menu(self,check=False): + # + normal_icon = os.path.join(comun.ICONDIR,'google-tasks-indicator-%s-normal.svg'%(self.theme)) + starred_icon = os.path.join(comun.ICONDIR,'google-tasks-indicator-%s-starred.svg'%(self.theme)) + # + self.indicator.set_icon(normal_icon) + self.indicator.set_attention_icon(starred_icon) + # + menu = Gtk.Menu() + # + self.indicator.set_status(appindicator.IndicatorStatus.ACTIVE) + self.menu_tasks = [] + for i in range(10): + menu_task = MenuNote(googletasksapi.Task()) + menu_task.show() + menu_task.set_visible(False) + menu_task.connect('activate',self.menu_check_item) + menu.append(menu_task) + self.menu_tasks.append(menu_task) + add2menu(menu) + self.mant = add2menu(menu, text = _('Add new task'), conector_event = 'activate',conector_action = self.menu_add_new_task) + self.mant.set_visible(self.tasklist_id is not None) + add2menu(menu, text = _('Add new task list'), conector_event = 'activate',conector_action = self.menu_add_new_tasklist) + add2menu(menu) + add2menu(menu, text = _('Refresh'), conector_event = 'activate',conector_action = self.menu_refresh) + add2menu(menu, text = _('Clear completed tasks'), conector_event = 'activate',conector_action = self.menu_clear_completed_tasks) + add2menu(menu, text = _('Show all tasks'), conector_event = 'activate',conector_action = self.menu_show_tasks) + add2menu(menu, text = _('Synchronize with Google'), conector_event = 'activate',conector_action = self.sync) + add2menu(menu) + add2menu(menu) + add2menu(menu, text = _('Preferences'), conector_event = 'activate',conector_action = self.menu_preferences_response) + add2menu(menu) + menu_help = add2menu(menu, text =_('Help')) + menu_help.set_submenu(self.get_help_menu()) + add2menu(menu) + add2menu(menu, text = _('Exit'), conector_event = 'activate',conector_action = self.menu_exit_response) + menu.show() + self.indicator.set_menu(menu) + + + def get_help_menu(self): + help_menu =Gtk.Menu() + # + add2menu(help_menu,text = _('Web...'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://launchpad.net/google-tasks-indicator')) + add2menu(help_menu,text = _('Get help online...'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://answers.launchpad.net/google-tasks-indicator')) + add2menu(help_menu,text = _('Translate this application...'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://translations.launchpad.net/google-tasks-indicator')) + add2menu(help_menu,text = _('Report a bug...'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://bugs.launchpad.net/google-tasks-indicator')) + add2menu(help_menu) + web = add2menu(help_menu,text = _('Homepage'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('http://www.atareao.es/tag/calendar-indicator')) + twitter = add2menu(help_menu,text = _('Follow us in Twitter'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://twitter.com/atareao')) + googleplus = add2menu(help_menu,text = _('Follow us in Google+'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('https://plus.google.com/118214486317320563625/posts')) + facebook = add2menu(help_menu,text = _('Follow us in Facebook'),conector_event = 'activate',conector_action = lambda x: webbrowser.open('http://www.facebook.com/elatareao')) + add2menu(help_menu) + self.menu_about = add2menu(help_menu,text = _('About'),conector_event = 'activate',conector_action = self.menu_about_response) + # + web.set_image(Gtk.Image.new_from_file(os.path.join(comun.SOCIALDIR,'web.svg'))) + web.set_always_show_image(True) + twitter.set_image(Gtk.Image.new_from_file(os.path.join(comun.SOCIALDIR,'twitter.svg'))) + twitter.set_always_show_image(True) + googleplus.set_image(Gtk.Image.new_from_file(os.path.join(comun.SOCIALDIR,'googleplus.svg'))) + googleplus.set_always_show_image(True) + facebook.set_image(Gtk.Image.new_from_file(os.path.join(comun.SOCIALDIR,'facebook.svg'))) + facebook.set_always_show_image(True) + # + help_menu.show() + return help_menu + + def menu_preferences_response(self,widget): + widget.set_sensitive(False) + p = Preferences(self.tasks) + if p.run() == Gtk.ResponseType.ACCEPT: + p.save_preferences() + p.destroy() + self.read_preferences() + self.menu_update() + widget.set_sensitive(True) + + def menu_edit_note(self,widget): + widget.set_sensitive(False) + note = widget.note + annd = NoteDialog(note = note) + if annd.run() == Gtk.ResponseType.ACCEPT: + atasklist = self.tasks.tasklists[annd.get_tasklist_id()] + note = self.tasks.create_task(self,atasklist,title) + note['notes'] = annd.get_notes() + note.set_completed(annd.is_completed()) + due = annd.get_due_date() + if due is not None: + note.set_due(due) + self.menu_update() + annd.destroy() + widget.set_active(widget.get_note()['status'] == 'completed') + widget.set_sensitive(True) + + def menu_check_item(self,widget): + completed = not widget.get_active() + atask = widget.get_note() + if 'notes' in atask.keys(): + notes = atask['notes'] + else: + notes = '' + atask.set_completed(iscompleted = not completed) + #self.tasks.tasklists[atask['tasklist_id']]['tasks'] + widget.set_note(atask) + widget.set_active(atask['status'] == 'completed') + + def menu_add_new_tasklist(self,widget): + widget.set_sensitive(False) + tld = TaskListDialog() + if tld.run() == Gtk.ResponseType.ACCEPT: + tld.hide() + new_tasklist = self.tasks.create_tasklist(tld.get_title()) + if self.tasklist_id is None: + self.tasklist_id = new_tasklist['id'] + self.mant.set_visible(self.tasklist_id is not None) + self.menu_update() + tld.destroy() + widget.set_sensitive(True) + + def menu_add_new_task(self,widget): + widget.set_sensitive(False) + annd = TaskDialog(tasks=self.tasks) + if annd.run() == Gtk.ResponseType.ACCEPT: + tasklist = self.tasks.tasklists[annd.get_tasklist_id()] + atask = self.tasks.create_task(tasklist,annd.get_title()) + atask['notes'] = annd.get_notes() + atask.set_completed(annd.is_completed()) + due = annd.get_due_date() + if due is not None: + atask.set_due(due) + self.menu_update() + annd.destroy() + widget.set_sensitive(True) + + + def menu_update(self): + self.mant.set_visible(self.tasklist_id is not None) + number_of_tasks = len(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:10]) + if number_of_tasks < 10: + for index,note in enumerate(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:number_of_tasks]): + self.menu_tasks[index].set_note(note) + self.menu_tasks[index].set_visible(True) + for index in range(number_of_tasks,10): + self.menu_tasks[index].set_visible(False) + else: + for index,note in enumerate(self.tasks.get_tasks(tasklist_id = self.tasklist_id)[:10]): + self.menu_tasks[index].set_note(note) + self.menu_tasks[index].set_visible(True) + + def menu_clear_completed_tasks(self,widget): + widget.set_sensitive(False) + self.tasks.clear_completed_tasks(tasklist_id = self.tasklist_id) + self.menu_update() + widget.set_sensitive(True) + + def menu_refresh(self,widget): + widget.set_sensitive(False) + self.menu_update() + widget.set_sensitive(True) + + def menu_show_tasks(self,widget): + widget.set_sensitive(False) + snd = ShowTasksDialog(self.tasks, self.tasklist_id) + snd.run() + snd.destroy() + widget.set_sensitive(True) + self.menu_update() + + def menu_exit_response(self,widget): + configuration = Configuration() + configuration.set('tasklist_id',self.tasklist_id) + configuration.save() + self.tasks.backup() + exit(0) + + def menu_about_response(self,widget): + widget.set_sensitive(False) + ad=Gtk.AboutDialog() + ad.set_name(comun.APPNAME) + ad.set_version(comun.VERSION) + ad.set_copyright('Copyrignt (c) 2012\nLorenzo Carbonell') + ad.set_comments(_('An indicator for Google Tasks')) + ad.set_license(''+ + 'This program is free software: you can redistribute it and/or modify it\n'+ + 'under the terms of the GNU General Public License as published by the\n'+ + 'Free Software Foundation, either version 3 of the License, or (at your option)\n'+ + 'any later version.\n\n'+ + 'This program is distributed in the hope that it will be useful, but\n'+ + 'WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY\n'+ + 'or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for\n'+ + 'more details.\n\n'+ + 'You should have received a copy of the GNU General Public License along with\n'+ + 'this program. If not, see .') + ad.set_website('http://www.atareao.es') + ad.set_website_label('http://www.atareao.es') + ad.set_authors(['Lorenzo Carbonell ']) + ad.set_documenters(['Lorenzo Carbonell ']) + ad.set_logo(GdkPixbuf.Pixbuf.new_from_file(comun.ICON)) + ad.set_program_name(comun.APPNAME) + ad.run() + ad.destroy() + widget.set_sensitive(True) + +if __name__ == "__main__": + Notify.init("google-tasks-indicator") + gti=GoogleTasksIndicator() + Gtk.main() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/logindialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/logindialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/logindialog.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/logindialog.py 2012-12-07 18:25:56.000000000 +0000 @@ -0,0 +1,75 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# +# LoginDialog +# +# +# Copyright (C) 2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +from gi.repository import Gtk +from gi.repository import WebKit +from gi.repository import GObject +import comun +class LoginDialog(Gtk.Dialog): + def __init__(self,url): + self.code = None + Gtk.Dialog.__init__(self) + self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) + self.set_title(comun.APP) + self.set_icon_from_file(comun.ICON) + # + vbox = Gtk.VBox(spacing = 5) + self.get_content_area().add(vbox) + hbox1 = Gtk.HBox() + vbox.pack_start(hbox1,True,True,0) + # + self.scrolledwindow1 = Gtk.ScrolledWindow() + self.scrolledwindow1.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + self.scrolledwindow1.set_shadow_type(Gtk.ShadowType.IN) + hbox1.pack_start(self.scrolledwindow1,True,True,0) + # + self.viewer = WebKit.WebView() + self.scrolledwindow1.add(self.viewer) + self.scrolledwindow1.set_size_request(600,420) + self.viewer.connect('navigation-policy-decision-requested', self.on_navigation_requested) + self.viewer.open(url) + # + self.show_all() + + #################################################################### + #########################BROWSER#################################### + #################################################################### + def on_navigation_requested(self, view, frame, req, nav, pol): + try: + uri = req.get_uri() + print(uri) + pos = uri.find('http://localhost/?code=') + if pos > -1: + self.code = uri[23:] + self.hide() + except Exception as e: + print(e) + print('Error') + #################################################################### + #########################ACTIONS#################################### + #################################################################### + +if __name__ == '__main__': + ld = LoginDialog('http://www.google.com') + ld.run() Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/__init__.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/__init__.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/anyjson.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/anyjson.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/anyjson.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/anyjson.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utility module to import a JSON module - -Hides all the messy details of exactly where -we get a simplejson module from. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - - -try: # pragma: no cover - # Should work for Python2.6 and higher. - import json as simplejson -except ImportError: # pragma: no cover - try: - import simplejson - except ImportError: - # Try to import from django, should work on App Engine - from django.utils import simplejson Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/anyjson.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/anyjson.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/appengine.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/appengine.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/appengine.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/appengine.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,526 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for Google App Engine - -Utilities for making it easier to use OAuth 2.0 on Google App Engine. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import base64 -import httplib2 -import logging -import pickle -import time - -import clientsecrets - -from anyjson import simplejson -from client import AccessTokenRefreshError -from client import AssertionCredentials -from client import Credentials -from client import Flow -from client import OAuth2WebServerFlow -from client import Storage -from google.appengine.api import memcache -from google.appengine.api import users -from google.appengine.api import app_identity -from google.appengine.ext import db -from google.appengine.ext import webapp -from google.appengine.ext.webapp.util import login_required -from google.appengine.ext.webapp.util import run_wsgi_app - -OAUTH2CLIENT_NAMESPACE = 'oauth2client#ns' - - -class InvalidClientSecretsError(Exception): - """The client_secrets.json file is malformed or missing required fields.""" - pass - - -class AppAssertionCredentials(AssertionCredentials): - """Credentials object for App Engine Assertion Grants - - This object will allow an App Engine application to identify itself to Google - and other OAuth 2.0 servers that can verify assertions. It can be used for - the purpose of accessing data stored under an account assigned to the App - Engine application itself. - - This credential does not require a flow to instantiate because it represents - a two legged flow, and therefore has all of the required information to - generate and refresh its own access tokens. - """ - - def __init__(self, scope, **kwargs): - """Constructor for AppAssertionCredentials - - Args: - scope: string or list of strings, scope(s) of the credentials being requested. - """ - if type(scope) is list: - scope = ' '.join(scope) - self.scope = scope - - super(AppAssertionCredentials, self).__init__( - None, - None, - None) - - @classmethod - def from_json(cls, json): - data = simplejson.loads(json) - return AppAssertionCredentials(data['scope']) - - def _refresh(self, http_request): - """Refreshes the access_token. - - Since the underlying App Engine app_identity implementation does its own - caching we can skip all the storage hoops and just to a refresh using the - API. - - Args: - http_request: callable, a callable that matches the method signature of - httplib2.Http.request, used to make the refresh request. - - Raises: - AccessTokenRefreshError: When the refresh fails. - """ - try: - (token, _) = app_identity.get_access_token(self.scope) - except app_identity.Error, e: - raise AccessTokenRefreshError(str(e)) - self.access_token = token - - -class FlowProperty(db.Property): - """App Engine datastore Property for Flow. - - Utility property that allows easy storage and retreival of an - oauth2client.Flow""" - - # Tell what the user type is. - data_type = Flow - - # For writing to datastore. - def get_value_for_datastore(self, model_instance): - flow = super(FlowProperty, - self).get_value_for_datastore(model_instance) - return db.Blob(pickle.dumps(flow)) - - # For reading from datastore. - def make_value_from_datastore(self, value): - if value is None: - return None - return pickle.loads(value) - - def validate(self, value): - if value is not None and not isinstance(value, Flow): - raise db.BadValueError('Property %s must be convertible ' - 'to a FlowThreeLegged instance (%s)' % - (self.name, value)) - return super(FlowProperty, self).validate(value) - - def empty(self, value): - return not value - - -class CredentialsProperty(db.Property): - """App Engine datastore Property for Credentials. - - Utility property that allows easy storage and retrieval of - oath2client.Credentials - """ - - # Tell what the user type is. - data_type = Credentials - - # For writing to datastore. - def get_value_for_datastore(self, model_instance): - logging.info("get: Got type " + str(type(model_instance))) - cred = super(CredentialsProperty, - self).get_value_for_datastore(model_instance) - if cred is None: - cred = '' - else: - cred = cred.to_json() - return db.Blob(cred) - - # For reading from datastore. - def make_value_from_datastore(self, value): - logging.info("make: Got type " + str(type(value))) - if value is None: - return None - if len(value) == 0: - return None - try: - credentials = Credentials.new_from_json(value) - except ValueError: - credentials = None - return credentials - - def validate(self, value): - value = super(CredentialsProperty, self).validate(value) - logging.info("validate: Got type " + str(type(value))) - if value is not None and not isinstance(value, Credentials): - raise db.BadValueError('Property %s must be convertible ' - 'to a Credentials instance (%s)' % - (self.name, value)) - #if value is not None and not isinstance(value, Credentials): - # return None - return value - - -class StorageByKeyName(Storage): - """Store and retrieve a single credential to and from - the App Engine datastore. - - This Storage helper presumes the Credentials - have been stored as a CredenialsProperty - on a datastore model class, and that entities - are stored by key_name. - """ - - def __init__(self, model, key_name, property_name, cache=None): - """Constructor for Storage. - - Args: - model: db.Model, model class - key_name: string, key name for the entity that has the credentials - property_name: string, name of the property that is a CredentialsProperty - cache: memcache, a write-through cache to put in front of the datastore - """ - self._model = model - self._key_name = key_name - self._property_name = property_name - self._cache = cache - - def locked_get(self): - """Retrieve Credential from datastore. - - Returns: - oauth2client.Credentials - """ - if self._cache: - json = self._cache.get(self._key_name) - if json: - return Credentials.new_from_json(json) - - credential = None - entity = self._model.get_by_key_name(self._key_name) - if entity is not None: - credential = getattr(entity, self._property_name) - if credential and hasattr(credential, 'set_store'): - credential.set_store(self) - if self._cache: - self._cache.set(self._key_name, credentials.to_json()) - - return credential - - def locked_put(self, credentials): - """Write a Credentials to the datastore. - - Args: - credentials: Credentials, the credentials to store. - """ - entity = self._model.get_or_insert(self._key_name) - setattr(entity, self._property_name, credentials) - entity.put() - if self._cache: - self._cache.set(self._key_name, credentials.to_json()) - - def locked_delete(self): - """Delete Credential from datastore.""" - - if self._cache: - self._cache.delete(self._key_name) - - entity = self._model.get_by_key_name(self._key_name) - if entity is not None: - entity.delete() - - -class CredentialsModel(db.Model): - """Storage for OAuth 2.0 Credentials - - Storage of the model is keyed by the user.user_id(). - """ - credentials = CredentialsProperty() - - -class OAuth2Decorator(object): - """Utility for making OAuth 2.0 easier. - - Instantiate and then use with oauth_required or oauth_aware - as decorators on webapp.RequestHandler methods. - - Example: - - decorator = OAuth2Decorator( - client_id='837...ent.com', - client_secret='Qh...wwI', - scope='https://www.googleapis.com/auth/plus') - - - class MainHandler(webapp.RequestHandler): - - @decorator.oauth_required - def get(self): - http = decorator.http() - # http is authorized with the user's Credentials and can be used - # in API calls - - """ - - def __init__(self, client_id, client_secret, scope, - auth_uri='https://accounts.google.com/o/oauth2/auth', - token_uri='https://accounts.google.com/o/oauth2/token', - user_agent=None, - message=None, **kwargs): - - """Constructor for OAuth2Decorator - - Args: - client_id: string, client identifier. - client_secret: string client secret. - scope: string or list of strings, scope(s) of the credentials being - requested. - auth_uri: string, URI for authorization endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - token_uri: string, URI for token endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - user_agent: string, User agent of your application, default to None. - message: Message to display if there are problems with the OAuth 2.0 - configuration. The message may contain HTML and will be presented on the - web interface for any method that uses the decorator. - **kwargs: dict, Keyword arguments are be passed along as kwargs to the - OAuth2WebServerFlow constructor. - """ - self.flow = OAuth2WebServerFlow(client_id, client_secret, scope, user_agent, - auth_uri, token_uri, **kwargs) - self.credentials = None - self._request_handler = None - self._message = message - self._in_error = False - - def _display_error_message(self, request_handler): - request_handler.response.out.write('') - request_handler.response.out.write(self._message) - request_handler.response.out.write('') - - def oauth_required(self, method): - """Decorator that starts the OAuth 2.0 dance. - - Starts the OAuth dance for the logged in user if they haven't already - granted access for this application. - - Args: - method: callable, to be decorated method of a webapp.RequestHandler - instance. - """ - - def check_oauth(request_handler, *args, **kwargs): - if self._in_error: - self._display_error_message(request_handler) - return - - user = users.get_current_user() - # Don't use @login_decorator as this could be used in a POST request. - if not user: - request_handler.redirect(users.create_login_url( - request_handler.request.uri)) - return - # Store the request URI in 'state' so we can use it later - self.flow.params['state'] = request_handler.request.url - self._request_handler = request_handler - self.credentials = StorageByKeyName( - CredentialsModel, user.user_id(), 'credentials').get() - - if not self.has_credentials(): - return request_handler.redirect(self.authorize_url()) - try: - method(request_handler, *args, **kwargs) - except AccessTokenRefreshError: - return request_handler.redirect(self.authorize_url()) - - return check_oauth - - def oauth_aware(self, method): - """Decorator that sets up for OAuth 2.0 dance, but doesn't do it. - - Does all the setup for the OAuth dance, but doesn't initiate it. - This decorator is useful if you want to create a page that knows - whether or not the user has granted access to this application. - From within a method decorated with @oauth_aware the has_credentials() - and authorize_url() methods can be called. - - Args: - method: callable, to be decorated method of a webapp.RequestHandler - instance. - """ - - def setup_oauth(request_handler, *args, **kwargs): - if self._in_error: - self._display_error_message(request_handler) - return - - user = users.get_current_user() - # Don't use @login_decorator as this could be used in a POST request. - if not user: - request_handler.redirect(users.create_login_url( - request_handler.request.uri)) - return - - - self.flow.params['state'] = request_handler.request.url - self._request_handler = request_handler - self.credentials = StorageByKeyName( - CredentialsModel, user.user_id(), 'credentials').get() - method(request_handler, *args, **kwargs) - return setup_oauth - - def has_credentials(self): - """True if for the logged in user there are valid access Credentials. - - Must only be called from with a webapp.RequestHandler subclassed method - that had been decorated with either @oauth_required or @oauth_aware. - """ - return self.credentials is not None and not self.credentials.invalid - - def authorize_url(self): - """Returns the URL to start the OAuth dance. - - Must only be called from with a webapp.RequestHandler subclassed method - that had been decorated with either @oauth_required or @oauth_aware. - """ - callback = self._request_handler.request.relative_url('/oauth2callback') - url = self.flow.step1_get_authorize_url(callback) - user = users.get_current_user() - memcache.set(user.user_id(), pickle.dumps(self.flow), - namespace=OAUTH2CLIENT_NAMESPACE) - return str(url) - - def http(self): - """Returns an authorized http instance. - - Must only be called from within an @oauth_required decorated method, or - from within an @oauth_aware decorated method where has_credentials() - returns True. - """ - return self.credentials.authorize(httplib2.Http()) - - -class OAuth2DecoratorFromClientSecrets(OAuth2Decorator): - """An OAuth2Decorator that builds from a clientsecrets file. - - Uses a clientsecrets file as the source for all the information when - constructing an OAuth2Decorator. - - Example: - - decorator = OAuth2DecoratorFromClientSecrets( - os.path.join(os.path.dirname(__file__), 'client_secrets.json') - scope='https://www.googleapis.com/auth/plus') - - - class MainHandler(webapp.RequestHandler): - - @decorator.oauth_required - def get(self): - http = decorator.http() - # http is authorized with the user's Credentials and can be used - # in API calls - """ - - def __init__(self, filename, scope, message=None): - """Constructor - - Args: - filename: string, File name of client secrets. - scope: string, Space separated list of scopes. - message: string, A friendly string to display to the user if the - clientsecrets file is missing or invalid. The message may contain HTML and - will be presented on the web interface for any method that uses the - decorator. - """ - try: - client_type, client_info = clientsecrets.loadfile(filename) - if client_type not in [clientsecrets.TYPE_WEB, clientsecrets.TYPE_INSTALLED]: - raise InvalidClientSecretsError('OAuth2Decorator doesn\'t support this OAuth 2.0 flow.') - super(OAuth2DecoratorFromClientSecrets, - self).__init__( - client_info['client_id'], - client_info['client_secret'], - scope, - client_info['auth_uri'], - client_info['token_uri'], - message) - except clientsecrets.InvalidClientSecretsError: - self._in_error = True - if message is not None: - self._message = message - else: - self._message = "Please configure your application for OAuth 2.0" - - -def oauth2decorator_from_clientsecrets(filename, scope, message=None): - """Creates an OAuth2Decorator populated from a clientsecrets file. - - Args: - filename: string, File name of client secrets. - scope: string, Space separated list of scopes. - message: string, A friendly string to display to the user if the - clientsecrets file is missing or invalid. The message may contain HTML and - will be presented on the web interface for any method that uses the - decorator. - - Returns: An OAuth2Decorator - - """ - return OAuth2DecoratorFromClientSecrets(filename, scope, message) - - -class OAuth2Handler(webapp.RequestHandler): - """Handler for the redirect_uri of the OAuth 2.0 dance.""" - - @login_required - def get(self): - error = self.request.get('error') - if error: - errormsg = self.request.get('error_description', error) - self.response.out.write( - 'The authorization request failed: %s' % errormsg) - else: - user = users.get_current_user() - flow = pickle.loads(memcache.get(user.user_id(), - namespace=OAUTH2CLIENT_NAMESPACE)) - # This code should be ammended with application specific error - # handling. The following cases should be considered: - # 1. What if the flow doesn't exist in memcache? Or is corrupt? - # 2. What if the step2_exchange fails? - if flow: - credentials = flow.step2_exchange(self.request.params) - StorageByKeyName( - CredentialsModel, user.user_id(), 'credentials').put(credentials) - self.redirect(str(self.request.get('state'))) - else: - # TODO Add error handling here. - pass - - -application = webapp.WSGIApplication([('/oauth2callback', OAuth2Handler)]) - - -def main(): - run_wsgi_app(application) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/client.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/client.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/client.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/client.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,1037 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""An OAuth 2.0 client. - -Tools for interacting with OAuth 2.0 protected resources. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import base64 -import clientsecrets -import copy -import datetime -import httplib2 -import logging -import os -import sys -import time -import urllib -import urlparse - -from anyjson import simplejson - -HAS_OPENSSL = False -try: - from oauth2client.crypt import Signer - from oauth2client.crypt import make_signed_jwt - from oauth2client.crypt import verify_signed_jwt_with_certs - HAS_OPENSSL = True -except ImportError: - pass - -try: - from urlparse import parse_qsl -except ImportError: - from cgi import parse_qsl - -logger = logging.getLogger(__name__) - -# Expiry is stored in RFC3339 UTC format -EXPIRY_FORMAT = '%Y-%m-%dT%H:%M:%SZ' - -# Which certs to use to validate id_tokens received. -ID_TOKEN_VERIFICATON_CERTS = 'https://www.googleapis.com/oauth2/v1/certs' - -# Constant to use for the out of band OAuth 2.0 flow. -OOB_CALLBACK_URN = 'urn:ietf:wg:oauth:2.0:oob' - - -class Error(Exception): - """Base error for this module.""" - pass - - -class FlowExchangeError(Error): - """Error trying to exchange an authorization grant for an access token.""" - pass - - -class AccessTokenRefreshError(Error): - """Error trying to refresh an expired access token.""" - pass - -class UnknownClientSecretsFlowError(Error): - """The client secrets file called for an unknown type of OAuth 2.0 flow. """ - pass - - -class AccessTokenCredentialsError(Error): - """Having only the access_token means no refresh is possible.""" - pass - - -class VerifyJwtTokenError(Error): - """Could on retrieve certificates for validation.""" - pass - - -def _abstract(): - raise NotImplementedError('You need to override this function') - - -class MemoryCache(object): - """httplib2 Cache implementation which only caches locally.""" - - def __init__(self): - self.cache = {} - - def get(self, key): - return self.cache.get(key) - - def set(self, key, value): - self.cache[key] = value - - def delete(self, key): - self.cache.pop(key, None) - - -class Credentials(object): - """Base class for all Credentials objects. - - Subclasses must define an authorize() method that applies the credentials to - an HTTP transport. - - Subclasses must also specify a classmethod named 'from_json' that takes a JSON - string as input and returns an instaniated Credentials object. - """ - - NON_SERIALIZED_MEMBERS = ['store'] - - def authorize(self, http): - """Take an httplib2.Http instance (or equivalent) and - authorizes it for the set of credentials, usually by - replacing http.request() with a method that adds in - the appropriate headers and then delegates to the original - Http.request() method. - """ - _abstract() - - def refresh(self, http): - """Forces a refresh of the access_token. - - Args: - http: httplib2.Http, an http object to be used to make the refresh - request. - """ - _abstract() - - def apply(self, headers): - """Add the authorization to the headers. - - Args: - headers: dict, the headers to add the Authorization header to. - """ - _abstract() - - def _to_json(self, strip): - """Utility function for creating a JSON representation of an instance of Credentials. - - Args: - strip: array, An array of names of members to not include in the JSON. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - t = type(self) - d = copy.copy(self.__dict__) - for member in strip: - del d[member] - if 'token_expiry' in d and isinstance(d['token_expiry'], datetime.datetime): - d['token_expiry'] = d['token_expiry'].strftime(EXPIRY_FORMAT) - # Add in information we will need later to reconsistitue this instance. - d['_class'] = t.__name__ - d['_module'] = t.__module__ - return simplejson.dumps(d) - - def to_json(self): - """Creating a JSON representation of an instance of Credentials. - - Returns: - string, a JSON representation of this instance, suitable to pass to - from_json(). - """ - return self._to_json(Credentials.NON_SERIALIZED_MEMBERS) - - @classmethod - def new_from_json(cls, s): - """Utility class method to instantiate a Credentials subclass from a JSON - representation produced by to_json(). - - Args: - s: string, JSON from to_json(). - - Returns: - An instance of the subclass of Credentials that was serialized with - to_json(). - """ - data = simplejson.loads(s) - # Find and call the right classmethod from_json() to restore the object. - module = data['_module'] - try: - m = __import__(module) - except ImportError: - # In case there's an object from the old package structure, update it - module = module.replace('.apiclient', '') - m = __import__(module) - - m = __import__(module, fromlist=module.split('.')[:-1]) - kls = getattr(m, data['_class']) - from_json = getattr(kls, 'from_json') - return from_json(s) - - -class Flow(object): - """Base class for all Flow objects.""" - pass - - -class Storage(object): - """Base class for all Storage objects. - - Store and retrieve a single credential. This class supports locking - such that multiple processes and threads can operate on a single - store. - """ - - def acquire_lock(self): - """Acquires any lock necessary to access this Storage. - - This lock is not reentrant.""" - pass - - def release_lock(self): - """Release the Storage lock. - - Trying to release a lock that isn't held will result in a - RuntimeError. - """ - pass - - def locked_get(self): - """Retrieve credential. - - The Storage lock must be held when this is called. - - Returns: - oauth2client.client.Credentials - """ - _abstract() - - def locked_put(self, credentials): - """Write a credential. - - The Storage lock must be held when this is called. - - Args: - credentials: Credentials, the credentials to store. - """ - _abstract() - - def locked_delete(self): - """Delete a credential. - - The Storage lock must be held when this is called. - """ - _abstract() - - def get(self): - """Retrieve credential. - - The Storage lock must *not* be held when this is called. - - Returns: - oauth2client.client.Credentials - """ - self.acquire_lock() - try: - return self.locked_get() - finally: - self.release_lock() - - def put(self, credentials): - """Write a credential. - - The Storage lock must be held when this is called. - - Args: - credentials: Credentials, the credentials to store. - """ - self.acquire_lock() - try: - self.locked_put(credentials) - finally: - self.release_lock() - - def delete(self): - """Delete credential. - - Frees any resources associated with storing the credential. - The Storage lock must *not* be held when this is called. - - Returns: - None - """ - self.acquire_lock() - try: - return self.locked_delete() - finally: - self.release_lock() - - -class OAuth2Credentials(Credentials): - """Credentials object for OAuth 2.0. - - Credentials can be applied to an httplib2.Http object using the authorize() - method, which then adds the OAuth 2.0 access token to each request. - - OAuth2Credentials objects may be safely pickled and unpickled. - """ - - def __init__(self, access_token, client_id, client_secret, refresh_token, - token_expiry, token_uri, user_agent, id_token=None): - """Create an instance of OAuth2Credentials. - - This constructor is not usually called by the user, instead - OAuth2Credentials objects are instantiated by the OAuth2WebServerFlow. - - Args: - access_token: string, access token. - client_id: string, client identifier. - client_secret: string, client secret. - refresh_token: string, refresh token. - token_expiry: datetime, when the access_token expires. - token_uri: string, URI of token endpoint. - user_agent: string, The HTTP User-Agent to provide for this application. - id_token: object, The identity of the resource owner. - - Notes: - store: callable, A callable that when passed a Credential - will store the credential back to where it came from. - This is needed to store the latest access_token if it - has expired and been refreshed. - """ - self.access_token = access_token - self.client_id = client_id - self.client_secret = client_secret - self.refresh_token = refresh_token - self.store = None - self.token_expiry = token_expiry - self.token_uri = token_uri - self.user_agent = user_agent - self.id_token = id_token - - # True if the credentials have been revoked or expired and can't be - # refreshed. - self.invalid = False - - def authorize(self, http): - """Authorize an httplib2.Http instance with these credentials. - - The modified http.request method will add authentication headers to each - request and will refresh access_tokens when a 401 is received on a - request. In addition the http.request method has a credentials property, - http.request.credentials, which is the Credentials object that authorized - it. - - Args: - http: An instance of httplib2.Http - or something that acts like it. - - Returns: - A modified instance of http that was passed in. - - Example: - - h = httplib2.Http() - h = credentials.authorize(h) - - You can't create a new OAuth subclass of httplib2.Authenication - because it never gets passed the absolute URI, which is needed for - signing. So instead we have to overload 'request' with a closure - that adds in the Authorization header and then calls the original - version of 'request()'. - """ - request_orig = http.request - - # The closure that will replace 'httplib2.Http.request'. - def new_request(uri, method='GET', body=None, headers=None, - redirections=httplib2.DEFAULT_MAX_REDIRECTS, - connection_type=None): - if not self.access_token: - logger.info('Attempting refresh to obtain initial access_token') - self._refresh(request_orig) - - # Modify the request headers to add the appropriate - # Authorization header. - if headers is None: - headers = {} - self.apply(headers) - - if self.user_agent is not None: - if 'user-agent' in headers: - headers['user-agent'] = self.user_agent + ' ' + headers['user-agent'] - else: - headers['user-agent'] = self.user_agent - - resp, content = request_orig(uri, method, body, headers, - redirections, connection_type) - - if resp.status == 401: - logger.info('Refreshing due to a 401') - self._refresh(request_orig) - self.apply(headers) - return request_orig(uri, method, body, headers, - redirections, connection_type) - else: - return (resp, content) - - # Replace the request method with our own closure. - http.request = new_request - - # Set credentials as a property of the request method. - setattr(http.request, 'credentials', self) - - return http - - def refresh(self, http): - """Forces a refresh of the access_token. - - Args: - http: httplib2.Http, an http object to be used to make the refresh - request. - """ - self._refresh(http.request) - - def apply(self, headers): - """Add the authorization to the headers. - - Args: - headers: dict, the headers to add the Authorization header to. - """ - headers['Authorization'] = 'Bearer ' + self.access_token - - def to_json(self): - return self._to_json(Credentials.NON_SERIALIZED_MEMBERS) - - @classmethod - def from_json(cls, s): - """Instantiate a Credentials object from a JSON description of it. The JSON - should have been produced by calling .to_json() on the object. - - Args: - data: dict, A deserialized JSON object. - - Returns: - An instance of a Credentials subclass. - """ - data = simplejson.loads(s) - if 'token_expiry' in data and not isinstance(data['token_expiry'], - datetime.datetime): - try: - data['token_expiry'] = datetime.datetime.strptime( - data['token_expiry'], EXPIRY_FORMAT) - except: - data['token_expiry'] = None - retval = OAuth2Credentials( - data['access_token'], - data['client_id'], - data['client_secret'], - data['refresh_token'], - data['token_expiry'], - data['token_uri'], - data['user_agent'], - data.get('id_token', None)) - retval.invalid = data['invalid'] - return retval - - @property - def access_token_expired(self): - """True if the credential is expired or invalid. - - If the token_expiry isn't set, we assume the token doesn't expire. - """ - if self.invalid: - return True - - if not self.token_expiry: - return False - - now = datetime.datetime.utcnow() - if now >= self.token_expiry: - logger.info('access_token is expired. Now: %s, token_expiry: %s', - now, self.token_expiry) - return True - return False - - def set_store(self, store): - """Set the Storage for the credential. - - Args: - store: Storage, an implementation of Stroage object. - This is needed to store the latest access_token if it - has expired and been refreshed. This implementation uses - locking to check for updates before updating the - access_token. - """ - self.store = store - - def _updateFromCredential(self, other): - """Update this Credential from another instance.""" - self.__dict__.update(other.__getstate__()) - - def __getstate__(self): - """Trim the state down to something that can be pickled.""" - d = copy.copy(self.__dict__) - del d['store'] - return d - - def __setstate__(self, state): - """Reconstitute the state of the object from being pickled.""" - self.__dict__.update(state) - self.store = None - - def _generate_refresh_request_body(self): - """Generate the body that will be used in the refresh request.""" - body = urllib.urlencode({ - 'grant_type': 'refresh_token', - 'client_id': self.client_id, - 'client_secret': self.client_secret, - 'refresh_token': self.refresh_token, - }) - return body - - def _generate_refresh_request_headers(self): - """Generate the headers that will be used in the refresh request.""" - headers = { - 'content-type': 'application/x-www-form-urlencoded', - } - - if self.user_agent is not None: - headers['user-agent'] = self.user_agent - - return headers - - def _refresh(self, http_request): - """Refreshes the access_token. - - This method first checks by reading the Storage object if available. - If a refresh is still needed, it holds the Storage lock until the - refresh is completed. - - Args: - http_request: callable, a callable that matches the method signature of - httplib2.Http.request, used to make the refresh request. - - Raises: - AccessTokenRefreshError: When the refresh fails. - """ - if not self.store: - self._do_refresh_request(http_request) - else: - self.store.acquire_lock() - try: - new_cred = self.store.locked_get() - if (new_cred and not new_cred.invalid and - new_cred.access_token != self.access_token): - logger.info('Updated access_token read from Storage') - self._updateFromCredential(new_cred) - else: - self._do_refresh_request(http_request) - finally: - self.store.release_lock() - - def _do_refresh_request(self, http_request): - """Refresh the access_token using the refresh_token. - - Args: - http_request: callable, a callable that matches the method signature of - httplib2.Http.request, used to make the refresh request. - - Raises: - AccessTokenRefreshError: When the refresh fails. - """ - body = self._generate_refresh_request_body() - headers = self._generate_refresh_request_headers() - - logger.info('Refresing access_token') - resp, content = http_request( - self.token_uri, method='POST', body=body, headers=headers) - if resp.status == 200: - # TODO(jcgregorio) Raise an error if loads fails? - d = simplejson.loads(content) - self.access_token = d['access_token'] - self.refresh_token = d.get('refresh_token', self.refresh_token) - if 'expires_in' in d: - self.token_expiry = datetime.timedelta( - seconds=int(d['expires_in'])) + datetime.datetime.utcnow() - else: - self.token_expiry = None - if self.store: - self.store.locked_put(self) - else: - # An {'error':...} response body means the token is expired or revoked, - # so we flag the credentials as such. - logger.error('Failed to retrieve access token: %s' % content) - error_msg = 'Invalid response %s.' % resp['status'] - try: - d = simplejson.loads(content) - if 'error' in d: - error_msg = d['error'] - self.invalid = True - if self.store: - self.store.locked_put(self) - except: - pass - raise AccessTokenRefreshError(error_msg) - - -class AccessTokenCredentials(OAuth2Credentials): - """Credentials object for OAuth 2.0. - - Credentials can be applied to an httplib2.Http object using the - authorize() method, which then signs each request from that object - with the OAuth 2.0 access token. This set of credentials is for the - use case where you have acquired an OAuth 2.0 access_token from - another place such as a JavaScript client or another web - application, and wish to use it from Python. Because only the - access_token is present it can not be refreshed and will in time - expire. - - AccessTokenCredentials objects may be safely pickled and unpickled. - - Usage: - credentials = AccessTokenCredentials('', - 'my-user-agent/1.0') - http = httplib2.Http() - http = credentials.authorize(http) - - Exceptions: - AccessTokenCredentialsExpired: raised when the access_token expires or is - revoked. - """ - - def __init__(self, access_token, user_agent): - """Create an instance of OAuth2Credentials - - This is one of the few types if Credentials that you should contrust, - Credentials objects are usually instantiated by a Flow. - - Args: - access_token: string, access token. - user_agent: string, The HTTP User-Agent to provide for this application. - - Notes: - store: callable, a callable that when passed a Credential - will store the credential back to where it came from. - """ - super(AccessTokenCredentials, self).__init__( - access_token, - None, - None, - None, - None, - None, - user_agent) - - - @classmethod - def from_json(cls, s): - data = simplejson.loads(s) - retval = AccessTokenCredentials( - data['access_token'], - data['user_agent']) - return retval - - def _refresh(self, http_request): - raise AccessTokenCredentialsError( - "The access_token is expired or invalid and can't be refreshed.") - - -class AssertionCredentials(OAuth2Credentials): - """Abstract Credentials object used for OAuth 2.0 assertion grants. - - This credential does not require a flow to instantiate because it - represents a two legged flow, and therefore has all of the required - information to generate and refresh its own access tokens. It must - be subclassed to generate the appropriate assertion string. - - AssertionCredentials objects may be safely pickled and unpickled. - """ - - def __init__(self, assertion_type, user_agent, - token_uri='https://accounts.google.com/o/oauth2/token', - **unused_kwargs): - """Constructor for AssertionFlowCredentials. - - Args: - assertion_type: string, assertion type that will be declared to the auth - server - user_agent: string, The HTTP User-Agent to provide for this application. - token_uri: string, URI for token endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - """ - super(AssertionCredentials, self).__init__( - None, - None, - None, - None, - None, - token_uri, - user_agent) - self.assertion_type = assertion_type - - def _generate_refresh_request_body(self): - assertion = self._generate_assertion() - - body = urllib.urlencode({ - 'assertion_type': self.assertion_type, - 'assertion': assertion, - 'grant_type': 'assertion', - }) - - return body - - def _generate_assertion(self): - """Generate the assertion string that will be used in the access token - request. - """ - _abstract() - -if HAS_OPENSSL: - # PyOpenSSL is not a prerequisite for oauth2client, so if it is missing then - # don't create the SignedJwtAssertionCredentials or the verify_id_token() - # method. - - class SignedJwtAssertionCredentials(AssertionCredentials): - """Credentials object used for OAuth 2.0 Signed JWT assertion grants. - - This credential does not require a flow to instantiate because it - represents a two legged flow, and therefore has all of the required - information to generate and refresh its own access tokens. - """ - - MAX_TOKEN_LIFETIME_SECS = 3600 # 1 hour in seconds - - def __init__(self, - service_account_name, - private_key, - scope, - private_key_password='notasecret', - user_agent=None, - token_uri='https://accounts.google.com/o/oauth2/token', - **kwargs): - """Constructor for SignedJwtAssertionCredentials. - - Args: - service_account_name: string, id for account, usually an email address. - private_key: string, private key in P12 format. - scope: string or list of strings, scope(s) of the credentials being - requested. - private_key_password: string, password for private_key. - user_agent: string, HTTP User-Agent to provide for this application. - token_uri: string, URI for token endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - kwargs: kwargs, Additional parameters to add to the JWT token, for - example prn=joe@xample.org.""" - - super(SignedJwtAssertionCredentials, self).__init__( - 'http://oauth.net/grant_type/jwt/1.0/bearer', - user_agent, - token_uri=token_uri, - ) - - if type(scope) is list: - scope = ' '.join(scope) - self.scope = scope - - self.private_key = private_key - self.private_key_password = private_key_password - self.service_account_name = service_account_name - self.kwargs = kwargs - - @classmethod - def from_json(cls, s): - data = simplejson.loads(s) - retval = SignedJwtAssertionCredentials( - data['service_account_name'], - data['private_key'], - data['private_key_password'], - data['scope'], - data['user_agent'], - data['token_uri'], - data['kwargs'] - ) - retval.invalid = data['invalid'] - return retval - - def _generate_assertion(self): - """Generate the assertion that will be used in the request.""" - now = long(time.time()) - payload = { - 'aud': self.token_uri, - 'scope': self.scope, - 'iat': now, - 'exp': now + SignedJwtAssertionCredentials.MAX_TOKEN_LIFETIME_SECS, - 'iss': self.service_account_name - } - payload.update(self.kwargs) - logging.debug(str(payload)) - - return make_signed_jwt( - Signer.from_string(self.private_key, self.private_key_password), - payload) - - # Only used in verify_id_token(), which is always calling to the same URI - # for the certs. - _cached_http = httplib2.Http(MemoryCache()) - - def verify_id_token(id_token, audience, http=None, - cert_uri=ID_TOKEN_VERIFICATON_CERTS): - """Verifies a signed JWT id_token. - - Args: - id_token: string, A Signed JWT. - audience: string, The audience 'aud' that the token should be for. - http: httplib2.Http, instance to use to make the HTTP request. Callers - should supply an instance that has caching enabled. - cert_uri: string, URI of the certificates in JSON format to - verify the JWT against. - - Returns: - The deserialized JSON in the JWT. - - Raises: - oauth2client.crypt.AppIdentityError if the JWT fails to verify. - """ - if http is None: - http = _cached_http - - resp, content = http.request(cert_uri) - - if resp.status == 200: - certs = simplejson.loads(content) - return verify_signed_jwt_with_certs(id_token, certs, audience) - else: - raise VerifyJwtTokenError('Status code: %d' % resp.status) - - -def _urlsafe_b64decode(b64string): - # Guard against unicode strings, which base64 can't handle. - b64string = b64string.encode('ascii') - padded = b64string + '=' * (4 - len(b64string) % 4) - return base64.urlsafe_b64decode(padded) - - -def _extract_id_token(id_token): - """Extract the JSON payload from a JWT. - - Does the extraction w/o checking the signature. - - Args: - id_token: string, OAuth 2.0 id_token. - - Returns: - object, The deserialized JSON payload. - """ - segments = id_token.split('.') - - if (len(segments) != 3): - raise VerifyJwtTokenError( - 'Wrong number of segments in token: %s' % id_token) - - return simplejson.loads(_urlsafe_b64decode(segments[1])) - - -class OAuth2WebServerFlow(Flow): - """Does the Web Server Flow for OAuth 2.0. - - OAuth2Credentials objects may be safely pickled and unpickled. - """ - - def __init__(self, client_id, client_secret, scope, user_agent=None, - auth_uri='https://accounts.google.com/o/oauth2/auth', - token_uri='https://accounts.google.com/o/oauth2/token', - **kwargs): - """Constructor for OAuth2WebServerFlow. - - Args: - client_id: string, client identifier. - client_secret: string client secret. - scope: string or list of strings, scope(s) of the credentials being - requested. - user_agent: string, HTTP User-Agent to provide for this application. - auth_uri: string, URI for authorization endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - token_uri: string, URI for token endpoint. For convenience - defaults to Google's endpoints but any OAuth 2.0 provider can be used. - **kwargs: dict, The keyword arguments are all optional and required - parameters for the OAuth calls. - """ - self.client_id = client_id - self.client_secret = client_secret - if type(scope) is list: - scope = ' '.join(scope) - self.scope = scope - self.user_agent = user_agent - self.auth_uri = auth_uri - self.token_uri = token_uri - self.params = { - 'access_type': 'offline', - } - self.params.update(kwargs) - self.redirect_uri = None - - def step1_get_authorize_url(self, redirect_uri=OOB_CALLBACK_URN): - """Returns a URI to redirect to the provider. - - Args: - redirect_uri: string, Either the string 'urn:ietf:wg:oauth:2.0:oob' for - a non-web-based application, or a URI that handles the callback from - the authorization server. - - If redirect_uri is 'urn:ietf:wg:oauth:2.0:oob' then pass in the - generated verification code to step2_exchange, - otherwise pass in the query parameters received - at the callback uri to step2_exchange. - """ - - self.redirect_uri = redirect_uri - query = { - 'response_type': 'code', - 'client_id': self.client_id, - 'redirect_uri': redirect_uri, - 'scope': self.scope, - } - query.update(self.params) - parts = list(urlparse.urlparse(self.auth_uri)) - query.update(dict(parse_qsl(parts[4]))) # 4 is the index of the query part - parts[4] = urllib.urlencode(query) - return urlparse.urlunparse(parts) - - def step2_exchange(self, code, http=None): - """Exhanges a code for OAuth2Credentials. - - Args: - code: string or dict, either the code as a string, or a dictionary - of the query parameters to the redirect_uri, which contains - the code. - http: httplib2.Http, optional http instance to use to do the fetch - """ - - if not (isinstance(code, str) or isinstance(code, unicode)): - code = code['code'] - - body = urllib.urlencode({ - 'grant_type': 'authorization_code', - 'client_id': self.client_id, - 'client_secret': self.client_secret, - 'code': code, - 'redirect_uri': self.redirect_uri, - 'scope': self.scope, - }) - headers = { - 'content-type': 'application/x-www-form-urlencoded', - } - - if self.user_agent is not None: - headers['user-agent'] = self.user_agent - - if http is None: - http = httplib2.Http() - - resp, content = http.request(self.token_uri, method='POST', body=body, - headers=headers) - if resp.status == 200: - # TODO(jcgregorio) Raise an error if simplejson.loads fails? - d = simplejson.loads(content) - access_token = d['access_token'] - refresh_token = d.get('refresh_token', None) - token_expiry = None - if 'expires_in' in d: - token_expiry = datetime.datetime.utcnow() + datetime.timedelta( - seconds=int(d['expires_in'])) - - if 'id_token' in d: - d['id_token'] = _extract_id_token(d['id_token']) - - logger.info('Successfully retrieved access token: %s' % content) - return OAuth2Credentials(access_token, self.client_id, - self.client_secret, refresh_token, token_expiry, - self.token_uri, self.user_agent, - id_token=d.get('id_token', None)) - else: - logger.error('Failed to retrieve access token: %s' % content) - error_msg = 'Invalid response %s.' % resp['status'] - try: - d = simplejson.loads(content) - if 'error' in d: - error_msg = d['error'] - except: - pass - - raise FlowExchangeError(error_msg) - -def flow_from_clientsecrets(filename, scope, message=None): - """Create a Flow from a clientsecrets file. - - Will create the right kind of Flow based on the contents of the clientsecrets - file or will raise InvalidClientSecretsError for unknown types of Flows. - - Args: - filename: string, File name of client secrets. - scope: string or list of strings, scope(s) to request. - message: string, A friendly string to display to the user if the - clientsecrets file is missing or invalid. If message is provided then - sys.exit will be called in the case of an error. If message in not - provided then clientsecrets.InvalidClientSecretsError will be raised. - - Returns: - A Flow object. - - Raises: - UnknownClientSecretsFlowError if the file describes an unknown kind of Flow. - clientsecrets.InvalidClientSecretsError if the clientsecrets file is - invalid. - """ - try: - client_type, client_info = clientsecrets.loadfile(filename) - if client_type in [clientsecrets.TYPE_WEB, clientsecrets.TYPE_INSTALLED]: - return OAuth2WebServerFlow( - client_info['client_id'], - client_info['client_secret'], - scope, - None, # user_agent - client_info['auth_uri'], - client_info['token_uri']) - except clientsecrets.InvalidClientSecretsError: - if message: - sys.exit(message) - else: - raise - else: - raise UnknownClientSecretsFlowError( - 'This OAuth 2.0 flow is unsupported: "%s"' * client_type) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/client.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/client.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/clientsecrets.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/clientsecrets.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/clientsecrets.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/clientsecrets.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -# Copyright (C) 2011 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for reading OAuth 2.0 client secret files. - -A client_secrets.json file contains all the information needed to interact with -an OAuth 2.0 protected service. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - - -from anyjson import simplejson - -# Properties that make a client_secrets.json file valid. -TYPE_WEB = 'web' -TYPE_INSTALLED = 'installed' - -VALID_CLIENT = { - TYPE_WEB: { - 'required': [ - 'client_id', - 'client_secret', - 'redirect_uris', - 'auth_uri', - 'token_uri'], - 'string': [ - 'client_id', - 'client_secret' - ] - }, - TYPE_INSTALLED: { - 'required': [ - 'client_id', - 'client_secret', - 'redirect_uris', - 'auth_uri', - 'token_uri'], - 'string': [ - 'client_id', - 'client_secret' - ] - } - } - -class Error(Exception): - """Base error for this module.""" - pass - - -class InvalidClientSecretsError(Error): - """Format of ClientSecrets file is invalid.""" - pass - - -def _validate_clientsecrets(obj): - if obj is None or len(obj) != 1: - raise InvalidClientSecretsError('Invalid file format.') - client_type = obj.keys()[0] - if client_type not in VALID_CLIENT.keys(): - raise InvalidClientSecretsError('Unknown client type: %s.' % client_type) - client_info = obj[client_type] - for prop_name in VALID_CLIENT[client_type]['required']: - if prop_name not in client_info: - raise InvalidClientSecretsError( - 'Missing property "%s" in a client type of "%s".' % (prop_name, - client_type)) - for prop_name in VALID_CLIENT[client_type]['string']: - if client_info[prop_name].startswith('[['): - raise InvalidClientSecretsError( - 'Property "%s" is not configured.' % prop_name) - return client_type, client_info - - -def load(fp): - obj = simplejson.load(fp) - return _validate_clientsecrets(obj) - - -def loads(s): - obj = simplejson.loads(s) - return _validate_clientsecrets(obj) - - -def loadfile(filename): - try: - fp = file(filename, 'r') - try: - obj = simplejson.load(fp) - finally: - fp.close() - except IOError: - raise InvalidClientSecretsError('File not found: "%s"' % filename) - return _validate_clientsecrets(obj) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/clientsecrets.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/clientsecrets.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/crypt.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/crypt.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/crypt.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/crypt.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,244 +0,0 @@ -#!/usr/bin/python2.4 -# -*- coding: utf-8 -*- -# -# Copyright (C) 2011 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import base64 -import hashlib -import logging -import time - -from OpenSSL import crypto -from anyjson import simplejson - - -CLOCK_SKEW_SECS = 300 # 5 minutes in seconds -AUTH_TOKEN_LIFETIME_SECS = 300 # 5 minutes in seconds -MAX_TOKEN_LIFETIME_SECS = 86400 # 1 day in seconds - - -class AppIdentityError(Exception): - pass - - -class Verifier(object): - """Verifies the signature on a message.""" - - def __init__(self, pubkey): - """Constructor. - - Args: - pubkey, OpenSSL.crypto.PKey, The public key to verify with. - """ - self._pubkey = pubkey - - def verify(self, message, signature): - """Verifies a message against a signature. - - Args: - message: string, The message to verify. - signature: string, The signature on the message. - - Returns: - True if message was singed by the private key associated with the public - key that this object was constructed with. - """ - try: - crypto.verify(self._pubkey, signature, message, 'sha256') - return True - except: - return False - - @staticmethod - def from_string(key_pem, is_x509_cert): - """Construct a Verified instance from a string. - - Args: - key_pem: string, public key in PEM format. - is_x509_cert: bool, True if key_pem is an X509 cert, otherwise it is - expected to be an RSA key in PEM format. - - Returns: - Verifier instance. - - Raises: - OpenSSL.crypto.Error if the key_pem can't be parsed. - """ - if is_x509_cert: - pubkey = crypto.load_certificate(crypto.FILETYPE_PEM, key_pem) - else: - pubkey = crypto.load_privatekey(crypto.FILETYPE_PEM, key_pem) - return Verifier(pubkey) - - -class Signer(object): - """Signs messages with a private key.""" - - def __init__(self, pkey): - """Constructor. - - Args: - pkey, OpenSSL.crypto.PKey, The private key to sign with. - """ - self._key = pkey - - def sign(self, message): - """Signs a message. - - Args: - message: string, Message to be signed. - - Returns: - string, The signature of the message for the given key. - """ - return crypto.sign(self._key, message, 'sha256') - - @staticmethod - def from_string(key, password='notasecret'): - """Construct a Signer instance from a string. - - Args: - key: string, private key in P12 format. - password: string, password for the private key file. - - Returns: - Signer instance. - - Raises: - OpenSSL.crypto.Error if the key can't be parsed. - """ - pkey = crypto.load_pkcs12(key, password).get_privatekey() - return Signer(pkey) - - -def _urlsafe_b64encode(raw_bytes): - return base64.urlsafe_b64encode(raw_bytes).rstrip('=') - - -def _urlsafe_b64decode(b64string): - # Guard against unicode strings, which base64 can't handle. - b64string = b64string.encode('ascii') - padded = b64string + '=' * (4 - len(b64string) % 4) - return base64.urlsafe_b64decode(padded) - - -def _json_encode(data): - return simplejson.dumps(data, separators = (',', ':')) - - -def make_signed_jwt(signer, payload): - """Make a signed JWT. - - See http://self-issued.info/docs/draft-jones-json-web-token.html. - - Args: - signer: crypt.Signer, Cryptographic signer. - payload: dict, Dictionary of data to convert to JSON and then sign. - - Returns: - string, The JWT for the payload. - """ - header = {'typ': 'JWT', 'alg': 'RS256'} - - segments = [ - _urlsafe_b64encode(_json_encode(header)), - _urlsafe_b64encode(_json_encode(payload)), - ] - signing_input = '.'.join(segments) - - signature = signer.sign(signing_input) - segments.append(_urlsafe_b64encode(signature)) - - logging.debug(str(segments)) - - return '.'.join(segments) - - -def verify_signed_jwt_with_certs(jwt, certs, audience): - """Verify a JWT against public certs. - - See http://self-issued.info/docs/draft-jones-json-web-token.html. - - Args: - jwt: string, A JWT. - certs: dict, Dictionary where values of public keys in PEM format. - audience: string, The audience, 'aud', that this JWT should contain. If - None then the JWT's 'aud' parameter is not verified. - - Returns: - dict, The deserialized JSON payload in the JWT. - - Raises: - AppIdentityError if any checks are failed. - """ - segments = jwt.split('.') - - if (len(segments) != 3): - raise AppIdentityError( - 'Wrong number of segments in token: %s' % jwt) - signed = '%s.%s' % (segments[0], segments[1]) - - signature = _urlsafe_b64decode(segments[2]) - - # Parse token. - json_body = _urlsafe_b64decode(segments[1]) - try: - parsed = simplejson.loads(json_body) - except: - raise AppIdentityError('Can\'t parse token: %s' % json_body) - - # Check signature. - verified = False - for (keyname, pem) in certs.items(): - verifier = Verifier.from_string(pem, True) - if (verifier.verify(signed, signature)): - verified = True - break - if not verified: - raise AppIdentityError('Invalid token signature: %s' % jwt) - - # Check creation timestamp. - iat = parsed.get('iat') - if iat is None: - raise AppIdentityError('No iat field in token: %s' % json_body) - earliest = iat - CLOCK_SKEW_SECS - - # Check expiration timestamp. - now = long(time.time()) - exp = parsed.get('exp') - if exp is None: - raise AppIdentityError('No exp field in token: %s' % json_body) - if exp >= now + MAX_TOKEN_LIFETIME_SECS: - raise AppIdentityError( - 'exp field too far in future: %s' % json_body) - latest = exp + CLOCK_SKEW_SECS - - if now < earliest: - raise AppIdentityError('Token used too early, %d < %d: %s' % - (now, earliest, json_body)) - if now > latest: - raise AppIdentityError('Token used too late, %d > %d: %s' % - (now, latest, json_body)) - - # Check audience. - if audience is not None: - aud = parsed.get('aud') - if aud is None: - raise AppIdentityError('No aud field in token: %s' % json_body) - if aud != audience: - raise AppIdentityError('Wrong recipient, %s != %s: %s' % - (aud, audience, json_body)) - - return parsed Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/crypt.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/crypt.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/django_orm.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/django_orm.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/django_orm.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/django_orm.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,120 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""OAuth 2.0 utilities for Django. - -Utilities for using OAuth 2.0 in conjunction with -the Django datastore. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import oauth2client -import base64 -import pickle - -from django.db import models -from oauth2client.client import Storage as BaseStorage - -class CredentialsField(models.Field): - - __metaclass__ = models.SubfieldBase - - def get_internal_type(self): - return "TextField" - - def to_python(self, value): - if not value: - return None - if isinstance(value, oauth2client.client.Credentials): - return value - return pickle.loads(base64.b64decode(value)) - - def get_db_prep_value(self, value, connection, prepared=False): - return base64.b64encode(pickle.dumps(value)) - - -class FlowField(models.Field): - - __metaclass__ = models.SubfieldBase - - def get_internal_type(self): - return "TextField" - - def to_python(self, value): - if value is None: - return None - if isinstance(value, oauth2client.client.Flow): - return value - return pickle.loads(base64.b64decode(value)) - - def get_db_prep_value(self, value, connection, prepared=False): - return base64.b64encode(pickle.dumps(value)) - - -class Storage(BaseStorage): - """Store and retrieve a single credential to and from - the datastore. - - This Storage helper presumes the Credentials - have been stored as a CredenialsField - on a db model class. - """ - - def __init__(self, model_class, key_name, key_value, property_name): - """Constructor for Storage. - - Args: - model: db.Model, model class - key_name: string, key name for the entity that has the credentials - key_value: string, key value for the entity that has the credentials - property_name: string, name of the property that is an CredentialsProperty - """ - self.model_class = model_class - self.key_name = key_name - self.key_value = key_value - self.property_name = property_name - - def locked_get(self): - """Retrieve Credential from datastore. - - Returns: - oauth2client.Credentials - """ - credential = None - - query = {self.key_name: self.key_value} - entities = self.model_class.objects.filter(**query) - if len(entities) > 0: - credential = getattr(entities[0], self.property_name) - if credential and hasattr(credential, 'set_store'): - credential.set_store(self) - return credential - - def locked_put(self, credentials): - """Write a Credentials to the datastore. - - Args: - credentials: Credentials, the credentials to store. - """ - args = {self.key_name: self.key_value} - entity = self.model_class(**args) - setattr(entity, self.property_name, credentials) - entity.save() - - def locked_delete(self): - """Delete Credentials from the datastore.""" - - query = {self.key_name: self.key_value} - entities = self.model_class.objects.filter(**query).delete() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/file.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/file.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/file.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/file.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,107 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Utilities for OAuth. - -Utilities for making it easier to work with OAuth 2.0 -credentials. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' - -import os -import stat -import threading - -from anyjson import simplejson -from client import Storage as BaseStorage -from client import Credentials - - -class Storage(BaseStorage): - """Store and retrieve a single credential to and from a file.""" - - def __init__(self, filename): - self._filename = filename - self._lock = threading.Lock() - - def acquire_lock(self): - """Acquires any lock necessary to access this Storage. - - This lock is not reentrant.""" - self._lock.acquire() - - def release_lock(self): - """Release the Storage lock. - - Trying to release a lock that isn't held will result in a - RuntimeError. - """ - self._lock.release() - - def locked_get(self): - """Retrieve Credential from file. - - Returns: - oauth2client.client.Credentials - """ - credentials = None - try: - f = open(self._filename, 'rb') - content = f.read() - f.close() - except IOError: - return credentials - - try: - credentials = Credentials.new_from_json(content) - credentials.set_store(self) - except ValueError: - pass - - return credentials - - def _create_file_if_needed(self): - """Create an empty file if necessary. - - This method will not initialize the file. Instead it implements a - simple version of "touch" to ensure the file has been created. - """ - if not os.path.exists(self._filename): - old_umask = os.umask(0177) - try: - open(self._filename, 'a+b').close() - finally: - os.umask(old_umask) - - def locked_put(self, credentials): - """Write Credentials to file. - - Args: - credentials: Credentials, the credentials to store. - """ - - self._create_file_if_needed() - f = open(self._filename, 'wb') - f.write(credentials.to_json()) - f.close() - - def locked_delete(self): - """Delete Credentials file. - - Args: - credentials: Credentials, the credentials to store. - """ - - os.unlink(self._filename) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/file.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/file.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/multistore_file.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/multistore_file.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/multistore_file.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/multistore_file.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,388 +0,0 @@ -# Copyright 2011 Google Inc. All Rights Reserved. - -"""Multi-credential file store with lock support. - -This module implements a JSON credential store where multiple -credentials can be stored in one file. That file supports locking -both in a single process and across processes. - -The credential themselves are keyed off of: -* client_id -* user_agent -* scope - -The format of the stored data is like so: -{ - 'file_version': 1, - 'data': [ - { - 'key': { - 'clientId': '', - 'userAgent': '', - 'scope': '' - }, - 'credential': { - # JSON serialized Credentials. - } - } - ] -} -""" - -__author__ = 'jbeda@google.com (Joe Beda)' - -import base64 -import errno -import fcntl -import logging -import os -import threading - -from anyjson import simplejson -from client import Storage as BaseStorage -from client import Credentials - -logger = logging.getLogger(__name__) - -# A dict from 'filename'->_MultiStore instances -_multistores = {} -_multistores_lock = threading.Lock() - - -class Error(Exception): - """Base error for this module.""" - pass - - -class NewerCredentialStoreError(Error): - """The credential store is a newer version that supported.""" - pass - - -def get_credential_storage(filename, client_id, user_agent, scope, - warn_on_readonly=True): - """Get a Storage instance for a credential. - - Args: - filename: The JSON file storing a set of credentials - client_id: The client_id for the credential - user_agent: The user agent for the credential - scope: string or list of strings, Scope(s) being requested - warn_on_readonly: if True, log a warning if the store is readonly - - Returns: - An object derived from client.Storage for getting/setting the - credential. - """ - filename = os.path.realpath(os.path.expanduser(filename)) - _multistores_lock.acquire() - try: - multistore = _multistores.setdefault( - filename, _MultiStore(filename, warn_on_readonly)) - finally: - _multistores_lock.release() - if type(scope) is list: - scope = ' '.join(scope) - return multistore._get_storage(client_id, user_agent, scope) - - -class _MultiStore(object): - """A file backed store for multiple credentials.""" - - def __init__(self, filename, warn_on_readonly=True): - """Initialize the class. - - This will create the file if necessary. - """ - self._filename = filename - self._thread_lock = threading.Lock() - self._file_handle = None - self._read_only = False - self._warn_on_readonly = warn_on_readonly - - self._create_file_if_needed() - - # Cache of deserialized store. This is only valid after the - # _MultiStore is locked or _refresh_data_cache is called. This is - # of the form of: - # - # (client_id, user_agent, scope) -> OAuth2Credential - # - # If this is None, then the store hasn't been read yet. - self._data = None - - class _Storage(BaseStorage): - """A Storage object that knows how to read/write a single credential.""" - - def __init__(self, multistore, client_id, user_agent, scope): - self._multistore = multistore - self._client_id = client_id - self._user_agent = user_agent - self._scope = scope - - def acquire_lock(self): - """Acquires any lock necessary to access this Storage. - - This lock is not reentrant. - """ - self._multistore._lock() - - def release_lock(self): - """Release the Storage lock. - - Trying to release a lock that isn't held will result in a - RuntimeError. - """ - self._multistore._unlock() - - def locked_get(self): - """Retrieve credential. - - The Storage lock must be held when this is called. - - Returns: - oauth2client.client.Credentials - """ - credential = self._multistore._get_credential( - self._client_id, self._user_agent, self._scope) - if credential: - credential.set_store(self) - return credential - - def locked_put(self, credentials): - """Write a credential. - - The Storage lock must be held when this is called. - - Args: - credentials: Credentials, the credentials to store. - """ - self._multistore._update_credential(credentials, self._scope) - - def locked_delete(self): - """Delete a credential. - - The Storage lock must be held when this is called. - - Args: - credentials: Credentials, the credentials to store. - """ - self._multistore._delete_credential(self._client_id, self._user_agent, - self._scope) - - def _create_file_if_needed(self): - """Create an empty file if necessary. - - This method will not initialize the file. Instead it implements a - simple version of "touch" to ensure the file has been created. - """ - if not os.path.exists(self._filename): - old_umask = os.umask(0177) - try: - open(self._filename, 'a+b').close() - finally: - os.umask(old_umask) - - def _lock(self): - """Lock the entire multistore.""" - self._thread_lock.acquire() - # Check to see if the file is writeable. - try: - self._file_handle = open(self._filename, 'r+b') - fcntl.lockf(self._file_handle.fileno(), fcntl.LOCK_EX) - except IOError, e: - if e.errno != errno.EACCES: - raise e - self._file_handle = open(self._filename, 'rb') - self._read_only = True - if self._warn_on_readonly: - logger.warn('The credentials file (%s) is not writable. Opening in ' - 'read-only mode. Any refreshed credentials will only be ' - 'valid for this run.' % self._filename) - if os.path.getsize(self._filename) == 0: - logger.debug('Initializing empty multistore file') - # The multistore is empty so write out an empty file. - self._data = {} - self._write() - elif not self._read_only or self._data is None: - # Only refresh the data if we are read/write or we haven't - # cached the data yet. If we are readonly, we assume is isn't - # changing out from under us and that we only have to read it - # once. This prevents us from whacking any new access keys that - # we have cached in memory but were unable to write out. - self._refresh_data_cache() - - def _unlock(self): - """Release the lock on the multistore.""" - if not self._read_only: - fcntl.lockf(self._file_handle.fileno(), fcntl.LOCK_UN) - self._file_handle.close() - self._thread_lock.release() - - def _locked_json_read(self): - """Get the raw content of the multistore file. - - The multistore must be locked when this is called. - - Returns: - The contents of the multistore decoded as JSON. - """ - assert self._thread_lock.locked() - self._file_handle.seek(0) - return simplejson.load(self._file_handle) - - def _locked_json_write(self, data): - """Write a JSON serializable data structure to the multistore. - - The multistore must be locked when this is called. - - Args: - data: The data to be serialized and written. - """ - assert self._thread_lock.locked() - if self._read_only: - return - self._file_handle.seek(0) - simplejson.dump(data, self._file_handle, sort_keys=True, indent=2) - self._file_handle.truncate() - - def _refresh_data_cache(self): - """Refresh the contents of the multistore. - - The multistore must be locked when this is called. - - Raises: - NewerCredentialStoreError: Raised when a newer client has written the - store. - """ - self._data = {} - try: - raw_data = self._locked_json_read() - except Exception: - logger.warn('Credential data store could not be loaded. ' - 'Will ignore and overwrite.') - return - - version = 0 - try: - version = raw_data['file_version'] - except Exception: - logger.warn('Missing version for credential data store. It may be ' - 'corrupt or an old version. Overwriting.') - if version > 1: - raise NewerCredentialStoreError( - 'Credential file has file_version of %d. ' - 'Only file_version of 1 is supported.' % version) - - credentials = [] - try: - credentials = raw_data['data'] - except (TypeError, KeyError): - pass - - for cred_entry in credentials: - try: - (key, credential) = self._decode_credential_from_json(cred_entry) - self._data[key] = credential - except: - # If something goes wrong loading a credential, just ignore it - logger.info('Error decoding credential, skipping', exc_info=True) - - def _decode_credential_from_json(self, cred_entry): - """Load a credential from our JSON serialization. - - Args: - cred_entry: A dict entry from the data member of our format - - Returns: - (key, cred) where the key is the key tuple and the cred is the - OAuth2Credential object. - """ - raw_key = cred_entry['key'] - client_id = raw_key['clientId'] - user_agent = raw_key['userAgent'] - scope = raw_key['scope'] - key = (client_id, user_agent, scope) - credential = None - credential = Credentials.new_from_json(simplejson.dumps(cred_entry['credential'])) - return (key, credential) - - def _write(self): - """Write the cached data back out. - - The multistore must be locked. - """ - raw_data = {'file_version': 1} - raw_creds = [] - raw_data['data'] = raw_creds - for (cred_key, cred) in self._data.items(): - raw_key = { - 'clientId': cred_key[0], - 'userAgent': cred_key[1], - 'scope': cred_key[2] - } - raw_cred = simplejson.loads(cred.to_json()) - raw_creds.append({'key': raw_key, 'credential': raw_cred}) - self._locked_json_write(raw_data) - - def _get_credential(self, client_id, user_agent, scope): - """Get a credential from the multistore. - - The multistore must be locked. - - Args: - client_id: The client_id for the credential - user_agent: The user agent for the credential - scope: A string for the scope(s) being requested - - Returns: - The credential specified or None if not present - """ - key = (client_id, user_agent, scope) - - return self._data.get(key, None) - - def _update_credential(self, cred, scope): - """Update a credential and write the multistore. - - This must be called when the multistore is locked. - - Args: - cred: The OAuth2Credential to update/set - scope: The scope(s) that this credential covers - """ - key = (cred.client_id, cred.user_agent, scope) - self._data[key] = cred - self._write() - - def _delete_credential(self, client_id, user_agent, scope): - """Delete a credential and write the multistore. - - This must be called when the multistore is locked. - - Args: - client_id: The client_id for the credential - user_agent: The user agent for the credential - scope: The scope(s) that this credential covers - """ - key = (client_id, user_agent, scope) - try: - del self._data[key] - except KeyError: - pass - self._write() - - def _get_storage(self, client_id, user_agent, scope): - """Get a Storage object to get/set a credential. - - This Storage is a 'view' into the multistore. - - Args: - client_id: The client_id for the credential - user_agent: The user agent for the credential - scope: A string for the scope(s) being requested - - Returns: - A Storage object that can be used to get/set this cred - """ - return self._Storage(self, client_id, user_agent, scope) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/tools.py google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/tools.py --- google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/tools.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/tools.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ -# Copyright (C) 2010 Google Inc. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -"""Command-line tools for authenticating via OAuth 2.0 - -Do the OAuth 2.0 Web Server dance for a command line application. Stores the -generated credentials in a common file that is used by other example apps in -the same directory. -""" - -__author__ = 'jcgregorio@google.com (Joe Gregorio)' -__all__ = ['run'] - - -import BaseHTTPServer -import gflags -import socket -import sys -import webbrowser - -from client import FlowExchangeError -from client import OOB_CALLBACK_URN - -try: - from urlparse import parse_qsl -except ImportError: - from cgi import parse_qsl - - -FLAGS = gflags.FLAGS - -gflags.DEFINE_boolean('auth_local_webserver', True, - ('Run a local web server to handle redirects during ' - 'OAuth authorization.')) - -gflags.DEFINE_string('auth_host_name', 'localhost', - ('Host name to use when running a local web server to ' - 'handle redirects during OAuth authorization.')) - -gflags.DEFINE_multi_int('auth_host_port', [8080, 8090], - ('Port to use when running a local web server to ' - 'handle redirects during OAuth authorization.')) - - -class ClientRedirectServer(BaseHTTPServer.HTTPServer): - """A server to handle OAuth 2.0 redirects back to localhost. - - Waits for a single request and parses the query parameters - into query_params and then stops serving. - """ - query_params = {} - - -class ClientRedirectHandler(BaseHTTPServer.BaseHTTPRequestHandler): - """A handler for OAuth 2.0 redirects back to localhost. - - Waits for a single request and parses the query parameters - into the servers query_params and then stops serving. - """ - - def do_GET(s): - """Handle a GET request. - - Parses the query parameters and prints a message - if the flow has completed. Note that we can't detect - if an error occurred. - """ - s.send_response(200) - s.send_header("Content-type", "text/html") - s.end_headers() - query = s.path.split('?', 1)[-1] - query = dict(parse_qsl(query)) - s.server.query_params = query - s.wfile.write("Authentication Status") - s.wfile.write("

The authentication flow has completed.

") - s.wfile.write("") - - def log_message(self, format, *args): - """Do not log messages to stdout while running as command line program.""" - pass - - -def run(flow, storage, http=None): - """Core code for a command-line application. - - Args: - flow: Flow, an OAuth 2.0 Flow to step through. - storage: Storage, a Storage to store the credential in. - http: An instance of httplib2.Http.request - or something that acts like it. - - Returns: - Credentials, the obtained credential. - """ - if FLAGS.auth_local_webserver: - success = False - port_number = 0 - for port in FLAGS.auth_host_port: - port_number = port - try: - httpd = ClientRedirectServer((FLAGS.auth_host_name, port), - ClientRedirectHandler) - except socket.error, e: - pass - else: - success = True - break - FLAGS.auth_local_webserver = success - - if FLAGS.auth_local_webserver: - oauth_callback = 'http://%s:%s/' % (FLAGS.auth_host_name, port_number) - else: - oauth_callback = OOB_CALLBACK_URN - authorize_url = flow.step1_get_authorize_url(oauth_callback) - - if FLAGS.auth_local_webserver: - webbrowser.open(authorize_url, new=1, autoraise=True) - print 'Your browser has been opened to visit:' - print - print ' ' + authorize_url - print - print 'If your browser is on a different machine then exit and re-run this' - print 'application with the command-line parameter ' - print - print ' --noauth_local_webserver' - print - else: - print 'Go to the following link in your browser:' - print - print ' ' + authorize_url - print - - code = None - if FLAGS.auth_local_webserver: - httpd.handle_request() - if 'error' in httpd.query_params: - sys.exit('Authentication request was rejected.') - if 'code' in httpd.query_params: - code = httpd.query_params['code'] - else: - print 'Failed to find "code" in the query parameters of the redirect.' - sys.exit('Try running with --noauth_local_webserver.') - else: - code = raw_input('Enter verification code: ').strip() - - try: - credential = flow.step2_exchange(code, http) - except FlowExchangeError, e: - sys.exit('Authentication has failed: %s' % e) - - storage.put(credential) - credential.set_store(storage) - print 'Authentication successful.' - - return credential Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/oauth2client/tools.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/oauth2client/tools.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/preferences_dialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/preferences_dialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/preferences_dialog.py 2012-03-31 17:07:44.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/preferences_dialog.py 2012-12-07 18:25:56.000000000 +0000 @@ -1,5 +1,5 @@ -#! /usr/bin/python -# -*- coding: iso-8859-15 -*- +#!/usr/bin/python +# -*- utf-8 -*- # __author__='atareao' __date__ ='$19/02/2012$' @@ -30,6 +30,8 @@ import locale import gettext from configurator import Configuration +from googletasksapi import GTAService +from logindialog import LoginDialog import comun locale.setlocale(locale.LC_ALL, '') @@ -39,9 +41,10 @@ class Preferences(Gtk.Dialog): - def __init__(self,gta = None): + def __init__(self,tasks=None): title = comun.APPNAME + ' | '+_('Preferences') Gtk.Dialog.__init__(self,title,None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT,Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL)) + self.set_position(Gtk.WindowPosition.CENTER_ALWAYS) self.set_size_request(400, 170) self.set_resizable(False) #self.set_icon_from_file(comun.ICON) @@ -53,43 +56,26 @@ # notebook = Gtk.Notebook() vbox0.add(notebook) - ''' # - frame1 = Gtk.Frame() - notebook.append_page(frame1,tab_label = Gtk.Label(_('Task Lists'))) - # - table1 = Gtk.Table(rows = 2, columns = 2, homogeneous = False) - table1.set_border_width(5) - table1.set_col_spacings(5) - table1.set_row_spacings(5) - frame1.add(table1) - ''' frame2 = Gtk.Frame() notebook.append_page(frame2,tab_label = Gtk.Label(_('Options'))) - table2 = Gtk.Table(rows = 2, columns = 2, homogeneous = False) + table2 = Gtk.Table(rows = 3, columns = 2, homogeneous = False) table2.set_border_width(5) table2.set_col_spacings(5) table2.set_row_spacings(5) frame2.add(table2) # - label11 = Gtk.Label(_('Task list')+':') - label11.set_alignment(0,.5) - table2.attach(label11,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) - # + label12 = Gtk.Label(_('Task List')+':') + label12.set_alignment(0,.5) + table2.attach(label12,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) # - liststore = Gtk.ListStore(str,str) - if gta: - for listitem in gta.get_tasklists(): - print listitem - liststore.append([listitem['title'],listitem['id']]) - else: - liststore.append(['@default','@default']) - self.entry1 = Gtk.ComboBox.new_with_model(model=liststore) + self.liststore = Gtk.ListStore(str,str) + self.entry2 = Gtk.ComboBox.new_with_model(model=self.liststore) renderer_text = Gtk.CellRendererText() - self.entry1.pack_start(renderer_text, True) - self.entry1.add_attribute(renderer_text, "text", 0) - self.entry1.set_active(0) - table2.attach(self.entry1,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) + self.entry2.pack_start(renderer_text, True) + self.entry2.add_attribute(renderer_text, "text", 0) + self.entry2.set_active(0) + table2.attach(self.entry2,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) # label22 = Gtk.Label(_('Autostart')+':') label22.set_alignment(0,.5) @@ -105,35 +91,153 @@ self.switch5 = Gtk.Switch() table2.attach(self.switch5,1,2,2,3, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) # - self.load_preferences(gta) + frame1 = Gtk.Frame() + notebook.append_page(frame1,tab_label = Gtk.Label(_('Sync options'))) + # + table1 = Gtk.Table(rows = 3, columns = 4, homogeneous = False) + table1.set_border_width(5) + table1.set_col_spacings(5) + table1.set_row_spacings(5) + frame1.add(table1) + # + label_so_1 = Gtk.Label(_('Tasks local only')+':') + label_so_1.set_alignment(0,.5) + table1.attach(label_so_1,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + self.option_tlo = {} + self.option_tlo['copy'] = Gtk.RadioButton(group=None,label=_('Copy to external')) + table1.attach(self.option_tlo['copy'],1,2,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_tlo['delete'] = Gtk.RadioButton(group=self.option_tlo['copy'],label=_('Delete local')) + table1.attach(self.option_tlo['delete'],2,3,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_tlo['none'] = Gtk.RadioButton(group=self.option_tlo['copy'],label=_('Do none')) + table1.attach(self.option_tlo['none'],3,4,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + label_so_1 = Gtk.Label(_('Tasks external only')+':') + label_so_1.set_alignment(0,.5) + table1.attach(label_so_1,0,1,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + self.option_teo = {} + self.option_teo['copy'] = Gtk.RadioButton(group=None,label=_('Copy to local')) + table1.attach(self.option_teo['copy'],1,2,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_teo['delete'] = Gtk.RadioButton(group=self.option_teo['copy'],label=_('Delete external')) + table1.attach(self.option_teo['delete'],2,3,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_teo['none'] = Gtk.RadioButton(group=self.option_teo['copy'],label=_('Do none')) + table1.attach(self.option_teo['none'],3,4,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + self.option_tb = {} + self.option_tb['copy local'] = Gtk.RadioButton(group=None,label=_('Copy to local')) + table1.attach(self.option_tb['copy local'],1,2,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_tb['copy external'] = Gtk.RadioButton(group=self.option_tb['copy local'],label=_('Copy to external')) + table1.attach(self.option_tb['copy external'],2,3,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + self.option_tb['none'] = Gtk.RadioButton(group=self.option_tb['copy local'],label=_('Do none')) + table1.attach(self.option_tb['none'],3,4,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + label_so_1 = Gtk.Label(_('Tasks local and external')+':') + label_so_1.set_alignment(0,.5) + table1.attach(label_so_1,0,1,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + + # + frame2 = Gtk.Frame() + notebook.append_page(frame2,tab_label = Gtk.Label(_('Login'))) + # + table2 = Gtk.Table(rows = 1, columns = 2, homogeneous = False) + table2.set_border_width(5) + table2.set_col_spacings(5) + table2.set_row_spacings(5) + frame2.add(table2) + # + label11 = Gtk.Label(_('Allow access to Google Tasks')+':') + label11.set_alignment(0,.5) + table2.attach(label11,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + # + self.switch1 = Gtk.Switch() + self.switch1.connect('button-press-event',self.on_switch1_changed) + self.switch1.connect('activate',self.on_switch1_changed) + table2.attach(self.switch1,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) + # + self.load_preferences(tasks) # self.show_all() - def load_preferences(self,gta): + def load_preferences(self,tasks): + self.switch1.set_active(os.path.exists(comun.TOKEN_FILE)) configuration = Configuration() if os.path.exists(os.path.join(os.getenv("HOME"),".config/autostart/google-tasks-indicator-autostart.desktop")): self.switch4.set_active(True) + if configuration.get('local') == 0: + self.option_tlo['copy'].set_active(True) + elif configuration.get('local') == 1: + self.option_tlo['delete'].set_active(True) + else: + self.option_tlo['none'].set_active(True) + # + if configuration.get('external') == 0: + self.option_teo['copy'].set_active(True) + elif configuration.get('external') == 1: + self.option_teo['delete'].set_active(True) + else: + self.option_teo['none'].set_active(True) + # + if configuration.get('both') == 0: + self.option_tb['copy local'].set_active(True) + elif configuration.get('both') == 1: + self.option_tb['copy external'].set_active(True) + else: + self.option_tb['none'].set_active(True) + # if configuration.get('theme') == 'light': self.switch5.set_active(True) else: self.switch5.set_active(False) tasklist_id = configuration.get('tasklist_id') - if gta: - for i,item in enumerate(self.entry1.get_model()): - if tasklist_id == item[1]: - self.entry1.set_active(i) - return + if tasks is not None: + self.liststore.clear() + self.liststore.append([_('All'),None]) + for tasklist in tasks.tasklists.values(): + self.liststore.append([tasklist['title'],tasklist['id']]) + if tasklist_id is None: + self.entry2.set_active(0) + else: + for i,item in enumerate(self.liststore): + print(tasklist_id,item[1]) + if tasklist_id == item[1]: + self.entry2.set_active(i) + break + + if os.path.exists(comun.TOKEN_FILE): + gta = GTAService(token_file = comun.TOKEN_FILE) + def save_preferences(self): configuration = Configuration() - tree_iter = self.entry1.get_active_iter() + tree_iter = self.entry2.get_active_iter() if tree_iter != None: - model = self.entry1.get_model() + model = self.entry2.get_model() tasklist_id = model[tree_iter][1] - configuration.set('tasklist_id',tasklist_id) + configuration.set('tasklist_id',tasklist_id) if self.switch5.get_active(): configuration.set('theme','light') else: configuration.set('theme','dark') + if self.option_tlo['copy'].get_active()==True: + configuration.set('local',0) + elif self.option_tlo['delete'].get_active()==True: + configuration.set('local',1) + else: + configuration.set('local',2) + if self.option_teo['copy'].get_active()==True: + configuration.set('external',0) + elif self.option_teo['delete'].get_active()==True: + configuration.set('external',1) + else: + configuration.set('external',2) + # + if self.option_tb['copy local'].get_active()==True: + configuration.set('both',0) + elif self.option_tb['copy external'].get_active()==True: + configuration.set('both',1) + else: + configuration.set('both',2) + # configuration.save() filestart = os.path.join(os.getenv("HOME"),".config/autostart/google-tasks-indicator-autostart.desktop") if self.switch4.get_active(): @@ -147,7 +251,36 @@ def close_application(self,widget): self.ok = False - + + def on_switch1_changed(self,widget,data): + if self.switch1.get_active(): + if os.path.exists(comun.TOKEN_FILE): + os.remove(comun.TOKEN_FILE) + else: + gta = GTAService(token_file = comun.TOKEN_FILE) + if gta.do_refresh_authorization() is None: + authorize_url = gta.get_authorize_url() + ld = LoginDialog(authorize_url) + ld.run() + gta.get_authorization(ld.code) + ld.destroy() + if gta.do_refresh_authorization() is None: + md = Gtk.MessageDialog( parent = self, + flags = Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT, + type = Gtk.MessageType.ERROR, + buttons = Gtk.ButtonsType.OK_CANCEL, + message_format = _('You have to authorize Google-Task-Indicator to use it, do you want to authorize?')) + if md.run() == Gtk.ResponseType.CANCEL: + exit(3) + else: + if gta.do_refresh_authorization() is None: + exit(3) + self.switch1.set_active(True) + self.liststore.clear() + self.liststore.append([_('All'),None]) + for tasklist in gta.get_tasklists().values(): + self.liststore.append([tasklist['title'],tasklist['id']]) + self.entry2.set_active(0) if __name__ == "__main__": p = Preferences() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/rfc3339.py google-tasks-indicator-0.0.5.1.quantal.1/src/rfc3339.py --- google-tasks-indicator-0.0.3.2~quantal/src/rfc3339.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/rfc3339.py 2012-12-07 18:25:56.000000000 +0000 @@ -0,0 +1,486 @@ +#!/usr/bin/python +## rfc3339.py -- Implementation of the majority of RFC 3339 for python. +# Copyright (c) 2008, 2009, 2010 LShift Ltd. +# +# 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. + +""" +Implementation of the majority of http://www.ietf.org/rfc/rfc3339.txt. + +Use datetime.datetime.isoformat() as an inverse of the various parsing +routines in this module. + +Limitations, with respect to RFC 3339: + + - Section 4.3, "Unknown Local Offset Convention", is not implemented. + + - Section 5.6, "Internet Date/Time Format", is the ONLY supported format + implemented by the various parsers in this module. (Section 5.6 is + reproduced in its entirety below.) + + - Section 5.7, "Restrictions", is left to the datetime.datetime constructor + to implement, with the exception of limits on timezone + minutes-east-of-UTC magnitude. In particular, leap seconds are not + addressed by this module. (And it appears that they are not supported + by datetime, either.) + +Potential Improvements: + + - Support for leap seconds. (There's a table of them in RFC 3339 itself, + and http://tf.nist.gov/pubs/bulletin/leapsecond.htm updates monthly.) + +Extensions beyond the RFC: + + - Accepts (but will not generate) dates formatted with a time-offset + missing a colon. (Implemented because Facebook are generating + broken RFC 3339 timestamps.) + +Here's an excerpt from RFC 3339 itself: + +5.6. Internet Date/Time Format + + The following profile of ISO 8601 [ISO8601] dates SHOULD be used in + new protocols on the Internet. This is specified using the syntax + description notation defined in [ABNF]. + + date-fullyear = 4DIGIT + date-month = 2DIGIT ; 01-12 + date-mday = 2DIGIT ; 01-28, 01-29, 01-30, 01-31 based on + ; month/year + time-hour = 2DIGIT ; 00-23 + time-minute = 2DIGIT ; 00-59 + time-second = 2DIGIT ; 00-58, 00-59, 00-60 based on leap second + ; rules + time-secfrac = "." 1*DIGIT + time-numoffset = ("+" / "-") time-hour ":" time-minute + time-offset = "Z" / time-numoffset + + partial-time = time-hour ":" time-minute ":" time-second + [time-secfrac] + full-date = date-fullyear "-" date-month "-" date-mday + full-time = partial-time time-offset + + date-time = full-date "T" full-time + + NOTE: Per [ABNF] and ISO8601, the "T" and "Z" characters in this + syntax may alternatively be lower case "t" or "z" respectively. + + This date/time format may be used in some environments or contexts + that distinguish between the upper- and lower-case letters 'A'-'Z' + and 'a'-'z' (e.g. XML). Specifications that use this format in + such environments MAY further limit the date/time syntax so that + the letters 'T' and 'Z' used in the date/time syntax must always + be upper case. Applications that generate this format SHOULD use + upper case letters. + + NOTE: ISO 8601 defines date and time separated by "T". + Applications using this syntax may choose, for the sake of + readability, to specify a full-date and full-time separated by + (say) a space character. +""" + +import datetime, time, calendar +import re + +__all__ = ["tzinfo", "UTC_TZ", "parse_date", "parse_datetime", "now", "utcfromtimestamp", "utctotimestamp", "datetimetostr", "timestamptostr", "strtotimestamp"] + +ZERO = datetime.timedelta(0) + +class tzinfo(datetime.tzinfo): + """ + Implementation of a fixed-offset tzinfo. + """ + def __init__(self, minutesEast = 0, name = 'Z'): + """ + minutesEast -> number of minutes east of UTC that this tzinfo represents. + name -> symbolic (but uninterpreted) name of this tzinfo. + """ + self.minutesEast = minutesEast + self.offset = datetime.timedelta(minutes = minutesEast) + self.name = name + + def utcoffset(self, dt): + """Returns minutesEast from the constructor, as a datetime.timedelta.""" + return self.offset + + def dst(self, dt): + """This is a fixed offset tzinfo, so always returns a zero timedelta.""" + return ZERO + + def tzname(self, dt): + """Returns the name from the constructor.""" + return self.name + + def __repr__(self): + """If minutesEast==0, prints specially as rfc3339.UTC_TZ.""" + if self.minutesEast == 0: + return "rfc3339.UTC_TZ" + else: + return "rfc3339.tzinfo(%s,%s)" % (self.minutesEast, repr(self.name)) + +UTC_TZ = tzinfo(0, 'Z') + +date_re_str = r'(\d\d\d\d)-(\d\d)-(\d\d)' +time_re_str = r'(\d\d):(\d\d):(\d\d)(\.(\d+))?([zZ]|(([-+])(\d\d):?(\d\d)))' + +def make_re(*parts): + return re.compile(r'^\s*' + ''.join(parts) + r'\s*$') + +date_re = make_re(date_re_str) +datetime_re = make_re(date_re_str, r'[ tT]', time_re_str) + +def parse_date(s): + """ + Given a string matching the 'full-date' production above, returns + a datetime.date instance. Any deviation from the allowed format + will produce a raised ValueError. + + >>> parse_date("2008-08-24") + datetime.date(2008, 8, 24) + >>> parse_date(" 2008-08-24 ") + datetime.date(2008, 8, 24) + >>> parse_date("2008-08-00") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 134, in parse_date + return datetime.date(int(y), int(m), int(d)) + ValueError: day is out of range for month + >>> parse_date("2008-06-31") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 134, in parse_date + return datetime.date(int(y), int(m), int(d)) + ValueError: day is out of range for month + >>> parse_date("2008-13-01") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 134, in parse_date + return datetime.date(int(y), int(m), int(d)) + ValueError: month must be in 1..12 + >>> parse_date("22008-01-01") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 136, in parse_date + raise ValueError('Invalid RFC 3339 date string', s) + ValueError: ('Invalid RFC 3339 date string', '22008-01-01') + >>> parse_date("2008-08-24").isoformat() + '2008-08-24' + """ + m = date_re.match(s) + if m: + (y, m, d) = m.groups() + return datetime.date(int(y), int(m), int(d)) + else: + raise ValueError('Invalid RFC 3339 date string', s) + +def _offset_to_tzname(offset): + """ + Converts an offset in minutes to an RFC 3339 "time-offset" string. + + >>> _offset_to_tzname(0) + '+00:00' + >>> _offset_to_tzname(-1) + '-00:01' + >>> _offset_to_tzname(-60) + '-01:00' + >>> _offset_to_tzname(-779) + '-12:59' + >>> _offset_to_tzname(1) + '+00:01' + >>> _offset_to_tzname(60) + '+01:00' + >>> _offset_to_tzname(779) + '+12:59' + """ + offset = int(offset) + if offset < 0: + tzsign = '-' + else: + tzsign = '+' + offset = abs(offset) + tzhour = offset / 60 + tzmin = offset % 60 + return '%s%02d:%02d' % (tzsign, tzhour, tzmin) + +def parse_datetime(s): + """ + Given a string matching the 'date-time' production above, returns + a datetime.datetime instance. Any deviation from the allowed + format will produce a raised ValueError. + + >>> parse_datetime("2008-08-24T00:00:00Z") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.UTC_TZ) + >>> parse_datetime(" 2008-08-24T00:00:00Z ") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.UTC_TZ) + >>> parse_datetime("2008-08-24T00:00:00") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 208, in parse_datetime + raise ValueError('Invalid RFC 3339 datetime string', s) + ValueError: ('Invalid RFC 3339 datetime string', '2008-08-24T00:00:00') + >>> parse_datetime("2008-08-24T00:00:00+00:00") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.UTC_TZ) + >>> parse_datetime("2008-08-24T00:00:00+01:00") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(60,'+01:00')) + >>> parse_datetime("2008-08-24T00:00:00-01:00") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(-60,'-01:00')) + >>> parse_datetime("2008-08-24T00:00:00-01:23") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(-83,'-01:23')) + >>> parse_datetime("2008-08-24T24:00:00Z") + Traceback (most recent call last): + File "", line 1, in + File "rfc3339.py", line 206, in parse_datetime + tz) + ValueError: hour must be in 0..23 + >>> midnightUTC = parse_datetime("2008-08-24T00:00:00Z") + >>> oneamBST = parse_datetime("2008-08-24T01:00:00+01:00") + >>> midnightUTC == oneamBST + True + >>> elevenpmUTC = parse_datetime("2008-08-23T23:00:00Z") + >>> midnightBST = parse_datetime("2008-08-24T00:00:00+01:00") + >>> midnightBST == elevenpmUTC + True + >>> elevenpmUTC.isoformat() + '2008-08-23T23:00:00+00:00' + >>> oneamBST.isoformat() + '2008-08-24T01:00:00+01:00' + >>> parse_datetime("2008-08-24T00:00:00.123Z").isoformat() + '2008-08-24T00:00:00.123000+00:00' + + Facebook generates incorrectly-formatted RFC 3339 timestamps, with + the time-offset missing the colon: + >>> parse_datetime("2008-08-24T00:00:00+0000") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.UTC_TZ) + >>> parse_datetime("2008-08-24T00:00:00+0100") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(60,'+01:00')) + >>> parse_datetime("2008-08-24T00:00:00-0100") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(-60,'-01:00')) + >>> parse_datetime("2008-08-24T00:00:00-0123") + datetime.datetime(2008, 8, 24, 0, 0, tzinfo=rfc3339.tzinfo(-83,'-01:23')) + + While we accept such broken time-offsets, we don't generate them: + >>> parse_datetime("2008-08-24T00:00:00+0100").isoformat() + '2008-08-24T00:00:00+01:00' + + Seconds don't have to be integers: + >>> parse_datetime("2008-08-24T00:00:11.25Z") + datetime.datetime(2008, 8, 24, 0, 0, 11, 250000, tzinfo=rfc3339.UTC_TZ) + >>> parse_datetime("2008-08-24T00:00:11.25-0123") + datetime.datetime(2008, 8, 24, 0, 0, 11, 250000, tzinfo=rfc3339.tzinfo(-83,'-01:23')) + >>> parse_datetime("2008-08-24T00:00:11.25+0123") + datetime.datetime(2008, 8, 24, 0, 0, 11, 250000, tzinfo=rfc3339.tzinfo(83,'+01:23')) + + Rendering non-integer seconds produces an acceptable, if + non-minimal result: + >>> parse_datetime("2008-08-24T00:00:11.25Z").isoformat() + '2008-08-24T00:00:11.250000+00:00' + """ + m = datetime_re.match(s) + if m: + (y, m, d, hour, min, sec, ignore1, frac_sec, wholetz, ignore2, tzsign, tzhour, tzmin) = \ + m.groups() + + if frac_sec: + frac_sec = float("0." + frac_sec) + else: + frac_sec = 0 + microsec = int((frac_sec * 1000000) + 0.5) + + if wholetz == 'z' or wholetz == 'Z': + tz = UTC_TZ + else: + tzhour = int(tzhour) + tzmin = int(tzmin) + offset = tzhour * 60 + tzmin + if offset == 0: + tz = UTC_TZ + else: + if tzhour > 24 or tzmin > 60 or offset > 1439: ## see tzinfo docs for the 1439 part + raise ValueError('Invalid timezone offset', s, wholetz) + + if tzsign == '-': + offset = -offset + tz = tzinfo(offset, _offset_to_tzname(offset)) + + return datetime.datetime(int(y), int(m), int(d), + int(hour), int(min), int(sec), microsec, + tz) + else: + raise ValueError('Invalid RFC 3339 datetime string', s) + +def now(): + """Return a timezone-aware datetime.datetime object in + rfc3339.UTC_TZ timezone, representing the current moment + (time.time()). Useful as a replacement for the (timezone-unaware) + datetime.datetime.now() method.""" + return utcfromtimestamp(time.time()) + +def _timedelta_to_seconds(timedelta): + ''' + >>> _timedelta_to_seconds(datetime.timedelta(hours=3)) + 10800 + >>> _timedelta_to_seconds(datetime.timedelta(hours=3, minutes=15)) + 11700 + ''' + return (timedelta.days * 86400 + timedelta.seconds + + timedelta.microseconds // 1000) + +def _timezone(utc_offset): + ''' + Return a string representing the timezone offset. + + >>> _timezone(0) + '+00:00' + >>> _timezone(3600) + '+01:00' + >>> _timezone(-28800) + '-08:00' + >>> _timezone(-1800) + '-00:30' + ''' + # Python's division uses floor(), not round() like in other languages: + # -1 / 2 == -1 and not -1 / 2 == 0 + # That's why we use abs(utc_offset). + hours = abs(utc_offset) // 3600 + minutes = abs(utc_offset) % 3600 // 60 + sign = (utc_offset < 0 and '-') or '+' + return '%c%02d:%02d' % (sign, hours, minutes) + +def _utc_offset(date, use_system_timezone): + ''' + Return the UTC offset of `date`. If `date` does not have any `tzinfo`, use + the timezone informations stored locally on the system. + + >>> if time.localtime().tm_isdst: + ... system_timezone = -time.altzone + ... else: + ... system_timezone = -time.timezone + >>> _utc_offset(datetime.datetime.now(), True) == system_timezone + True + >>> _utc_offset(datetime.datetime.now(), False) + 0 + ''' + if isinstance(date, datetime.datetime) and date.tzinfo is not None: + return _timedelta_to_seconds(date.dst() or date.utcoffset()) + elif use_system_timezone: + if date.year < 1970: + # We use 1972 because 1970 doesn't have a leap day (feb 29) + t = time.mktime(date.replace(year=1972).timetuple()) + else: + t = time.mktime(date.timetuple()) + if time.localtime(t).tm_isdst: # pragma: no cover + return -time.altzone + else: + return -time.timezone + else: + return 0 + +def _string(d, timezone): + return ('%04d-%02d-%02dT%02d:%02d:%02d%s' % + (d.year, d.month, d.day, d.hour, d.minute, d.second, timezone)) + +def rfc3339(date, utc=False, use_system_timezone=True): + ''' + Return a string formatted according to the :RFC:`3339`. If called with + `utc=True`, it normalizes `date` to the UTC date. If `date` does not have + any timezone information, uses the local timezone:: + + >>> d = datetime.datetime(2008, 4, 2, 20) + >>> rfc3339(d, utc=True, use_system_timezone=False) + '2008-04-02T20:00:00Z' + >>> rfc3339(d) # doctest: +ELLIPSIS + '2008-04-02T20:00:00...' + + If called with `user_system_timezone=False` don't use the local timezone if + `date` does not have timezone informations and consider the offset to UTC + to be zero:: + + >>> rfc3339(d, use_system_timezone=False) + '2008-04-02T20:00:00+00:00' + + `date` must be a `datetime.datetime`, `datetime.date` or a timestamp as + returned by `time.time()`:: + + >>> rfc3339(0, utc=True, use_system_timezone=False) + '1970-01-01T00:00:00Z' + >>> rfc3339(datetime.date(2008, 9, 6), utc=True, + ... use_system_timezone=False) + '2008-09-06T00:00:00Z' + >>> rfc3339(datetime.date(2008, 9, 6), + ... use_system_timezone=False) + '2008-09-06T00:00:00+00:00' + >>> rfc3339('foo bar') + Traceback (most recent call last): + ... + TypeError: Expected timestamp or date object. Got . + + For dates before January 1st 1970, the timezones will be the ones used in + 1970. It might not be accurate, but on most sytem there is no timezone + information before 1970. + ''' + # Try to convert timestamp to datetime + try: + if use_system_timezone: + date = datetime.datetime.fromtimestamp(date) + else: + date = datetime.datetime.utcfromtimestamp(date) + except TypeError: + pass + + if not isinstance(date, datetime.date): + raise TypeError('Expected timestamp or date object. Got %r.' % + type(date)) + + if not isinstance(date, datetime.datetime): + date = datetime.datetime(*date.timetuple()[:3]) + utc_offset = _utc_offset(date, use_system_timezone) + if utc: + return _string(date + datetime.timedelta(seconds=utc_offset), 'Z') + else: + return _string(date, _timezone(utc_offset)) + +def utcfromtimestamp(unix_epoch_timestamp): + """Interprets its argument as a count of seconds elapsed since the + Unix epoch, and returns a datetime.datetime in rfc3339.UTC_TZ + timezone.""" + (y, m, d, hour, min, sec) = time.gmtime(unix_epoch_timestamp)[:6] + return datetime.datetime(y, m, d, hour, min, sec, 0, UTC_TZ) + +def utctotimestamp(dt): + """Returns a count of the elapsed seconds between the Unix epoch + and the passed-in datetime.datetime object.""" + return calendar.timegm(dt.utctimetuple()) + +def datetimetostr(dt): + """Return a RFC3339 date-time string corresponding to the given + datetime object.""" + if dt.utcoffset() is not None: + return dt.isoformat() + else: + return "%sZ" % dt.isoformat() + +def timestamptostr(ts): + """Return a RFC3339 date-time string corresponding to the given + Unix-epoch timestamp.""" + return datetimetostr(utcfromtimestamp(ts)) + +def strtotimestamp(s): + """Return the Unix-epoch timestamp corresponding to the given RFC3339 + date-time string.""" + return utctotimestamp(parse_datetime(s)) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/rfc3339_temporal.py google-tasks-indicator-0.0.5.1.quantal.1/src/rfc3339_temporal.py --- google-tasks-indicator-0.0.3.2~quantal/src/rfc3339_temporal.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/rfc3339_temporal.py 2012-12-02 20:00:12.000000000 +0000 @@ -0,0 +1,282 @@ +#!/usr/bin/env python +# +# Copyright (c) 2009, 2010, Henry Precheur +# +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH +# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND +# FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, +# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM +# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR +# OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR +# PERFORMANCE OF THIS SOFTWARE. +# +'''Formats dates according to the :RFC:`3339`. + +Report bugs & problems on BitBucket_ + +.. _BitBucket: https://bitbucket.org/henry/clan.cx/issues +''' + +__author__ = 'Henry Precheur ' +__license__ = 'ISCL' +__version__ = '5.1' +__all__ = ('rfc3339', ) + +import datetime +import time +import unittest + +def _timezone(utc_offset): + ''' + Return a string representing the timezone offset. + + >>> _timezone(0) + '+00:00' + >>> _timezone(3600) + '+01:00' + >>> _timezone(-28800) + '-08:00' + >>> _timezone(-1800) + '-00:30' + ''' + # Python's division uses floor(), not round() like in other languages: + # -1 / 2 == -1 and not -1 / 2 == 0 + # That's why we use abs(utc_offset). + hours = abs(utc_offset) // 3600 + minutes = abs(utc_offset) % 3600 // 60 + sign = (utc_offset < 0 and '-') or '+' + return '%c%02d:%02d' % (sign, hours, minutes) + +def _timedelta_to_seconds(timedelta): + ''' + >>> _timedelta_to_seconds(datetime.timedelta(hours=3)) + 10800 + >>> _timedelta_to_seconds(datetime.timedelta(hours=3, minutes=15)) + 11700 + ''' + return (timedelta.days * 86400 + timedelta.seconds + + timedelta.microseconds // 1000) + +def _utc_offset(date, use_system_timezone): + ''' + Return the UTC offset of `date`. If `date` does not have any `tzinfo`, use + the timezone informations stored locally on the system. + + >>> if time.localtime().tm_isdst: + ... system_timezone = -time.altzone + ... else: + ... system_timezone = -time.timezone + >>> _utc_offset(datetime.datetime.now(), True) == system_timezone + True + >>> _utc_offset(datetime.datetime.now(), False) + 0 + ''' + if isinstance(date, datetime.datetime) and date.tzinfo is not None: + return _timedelta_to_seconds(date.dst() or date.utcoffset()) + elif use_system_timezone: + if date.year < 1970: + # We use 1972 because 1970 doesn't have a leap day (feb 29) + t = time.mktime(date.replace(year=1972).timetuple()) + else: + t = time.mktime(date.timetuple()) + if time.localtime(t).tm_isdst: # pragma: no cover + return -time.altzone + else: + return -time.timezone + else: + return 0 + +def _string(d, timezone): + return ('%04d-%02d-%02dT%02d:%02d:%02d%s' % + (d.year, d.month, d.day, d.hour, d.minute, d.second, timezone)) + +def rfc3339(date, utc=False, use_system_timezone=True): + ''' + Return a string formatted according to the :RFC:`3339`. If called with + `utc=True`, it normalizes `date` to the UTC date. If `date` does not have + any timezone information, uses the local timezone:: + + >>> d = datetime.datetime(2008, 4, 2, 20) + >>> rfc3339(d, utc=True, use_system_timezone=False) + '2008-04-02T20:00:00Z' + >>> rfc3339(d) # doctest: +ELLIPSIS + '2008-04-02T20:00:00...' + + If called with `user_system_timezone=False` don't use the local timezone if + `date` does not have timezone informations and consider the offset to UTC + to be zero:: + + >>> rfc3339(d, use_system_timezone=False) + '2008-04-02T20:00:00+00:00' + + `date` must be a `datetime.datetime`, `datetime.date` or a timestamp as + returned by `time.time()`:: + + >>> rfc3339(0, utc=True, use_system_timezone=False) + '1970-01-01T00:00:00Z' + >>> rfc3339(datetime.date(2008, 9, 6), utc=True, + ... use_system_timezone=False) + '2008-09-06T00:00:00Z' + >>> rfc3339(datetime.date(2008, 9, 6), + ... use_system_timezone=False) + '2008-09-06T00:00:00+00:00' + >>> rfc3339('foo bar') + Traceback (most recent call last): + ... + TypeError: Expected timestamp or date object. Got . + + For dates before January 1st 1970, the timezones will be the ones used in + 1970. It might not be accurate, but on most sytem there is no timezone + information before 1970. + ''' + # Try to convert timestamp to datetime + try: + if use_system_timezone: + date = datetime.datetime.fromtimestamp(date) + else: + date = datetime.datetime.utcfromtimestamp(date) + except TypeError: + pass + + if not isinstance(date, datetime.date): + raise TypeError('Expected timestamp or date object. Got %r.' % + type(date)) + + if not isinstance(date, datetime.datetime): + date = datetime.datetime(*date.timetuple()[:3]) + utc_offset = _utc_offset(date, use_system_timezone) + if utc: + return _string(date + datetime.timedelta(seconds=utc_offset), 'Z') + else: + return _string(date, _timezone(utc_offset)) + + +class LocalTimeTestCase(unittest.TestCase): + ''' + Test the use of the timezone saved locally. Since it is hard to test using + doctest. + ''' + + def setUp(self): + local_utcoffset = _utc_offset(datetime.datetime.now(), True) + self.local_utcoffset = datetime.timedelta(seconds=local_utcoffset) + self.local_timezone = _timezone(local_utcoffset) + + def test_datetime(self): + d = datetime.datetime.now() + self.assertEqual(rfc3339(d), + d.strftime('%Y-%m-%dT%H:%M:%S') + self.local_timezone) + + def test_datetime_timezone(self): + + class FixedNoDst(datetime.tzinfo): + 'A timezone info with fixed offset, not DST' + + def utcoffset(self, dt): + return datetime.timedelta(hours=2, minutes=30) + + def dst(self, dt): + return None + + fixed_no_dst = FixedNoDst() + + class Fixed(FixedNoDst): + 'A timezone info with DST' + + def dst(self, dt): + return datetime.timedelta(hours=3, minutes=15) + + fixed = Fixed() + + d = datetime.datetime.now().replace(tzinfo=fixed_no_dst) + timezone = _timezone(_timedelta_to_seconds(fixed_no_dst.\ + utcoffset(None))) + self.assertEqual(rfc3339(d), + d.strftime('%Y-%m-%dT%H:%M:%S') + timezone) + + d = datetime.datetime.now().replace(tzinfo=fixed) + timezone = _timezone(_timedelta_to_seconds(fixed.dst(None))) + self.assertEqual(rfc3339(d), + d.strftime('%Y-%m-%dT%H:%M:%S') + timezone) + + def test_datetime_utc(self): + d = datetime.datetime.now() + d_utc = d + self.local_utcoffset + self.assertEqual(rfc3339(d, utc=True), + d_utc.strftime('%Y-%m-%dT%H:%M:%SZ')) + + def test_date(self): + d = datetime.date.today() + self.assertEqual(rfc3339(d), + d.strftime('%Y-%m-%dT%H:%M:%S') + self.local_timezone) + + def test_date_utc(self): + d = datetime.date.today() + # Convert `date` to `datetime`, since `date` ignores seconds and hours + # in timedeltas: + # >>> datetime.date(2008, 9, 7) + datetime.timedelta(hours=23) + # datetime.date(2008, 9, 7) + d_utc = datetime.datetime(*d.timetuple()[:3]) + self.local_utcoffset + self.assertEqual(rfc3339(d, utc=True), + d_utc.strftime('%Y-%m-%dT%H:%M:%SZ')) + + def test_timestamp(self): + d = time.time() + self.assertEqual(rfc3339(d), + datetime.datetime.fromtimestamp(d).\ + strftime('%Y-%m-%dT%H:%M:%S') + self.local_timezone) + + def test_timestamp_utc(self): + d = time.time() + d_utc = datetime.datetime.utcfromtimestamp(d) + self.local_utcoffset + self.assertEqual(rfc3339(d), + (d_utc.strftime('%Y-%m-%dT%H:%M:%S') + + self.local_timezone)) + + def test_before_1970(self): + d = datetime.date(1885, 1, 4) + self.failUnless(rfc3339(d).startswith('1885-01-04T00:00:00')) + self.assertEqual(rfc3339(d, utc=True, use_system_timezone=False), + '1885-01-04T00:00:00Z') + + def test_1920(self): + d = datetime.date(1920, 2, 29) + x = rfc3339(d, utc=False, use_system_timezone=True) + self.failUnless(x.startswith('1920-02-29T00:00:00')) + + # If these tests start failing it probably means there was a policy change + # for the Pacific time zone. + # See http://en.wikipedia.org/wiki/Pacific_Time_Zone. + if 'PST' in time.tzname: + def testPDTChange(self): + '''Test Daylight saving change''' + # PDT switch happens at 2AM on March 14, 2010 + + # 1:59AM PST + self.assertEqual(rfc3339(datetime.datetime(2010, 3, 14, 1, 59)), + '2010-03-14T01:59:00-08:00') + # 3AM PDT + self.assertEqual(rfc3339(datetime.datetime(2010, 3, 14, 3, 0)), + '2010-03-14T03:00:00-07:00') + + def testPSTChange(self): + '''Test Standard time change''' + # PST switch happens at 2AM on November 6, 2010 + + # 0:59AM PDT + self.assertEqual(rfc3339(datetime.datetime(2010, 11, 7, 0, 59)), + '2010-11-07T00:59:00-07:00') + + # 1:00AM PST + # There's no way to have 1:00AM PST without a proper tzinfo + self.assertEqual(rfc3339(datetime.datetime(2010, 11, 7, 1, 0)), + '2010-11-07T01:00:00-07:00') + + +if __name__ == '__main__': # pragma: no cover + print(rfc3339(datetime.datetime.now())) + exit(0) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/services.py google-tasks-indicator-0.0.5.1.quantal.1/src/services.py --- google-tasks-indicator-0.0.3.2~quantal/src/services.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/services.py 2012-12-09 09:26:30.000000000 +0000 @@ -0,0 +1,408 @@ +#!/usr/bin/python +# -*- coding: utf-8 -*- +# +# +# services.py +# +# Copyright (C) 2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# + +import requests +import json +import os +from urllib.parse import urlencode +import random +import time +from logindialog import LoginDialog +import mimetypes +import io + + +KEY = '2eoegx5n62z1qyh' +SECRET = '9gsfezp3hc1xl44' +class DropboxService(object): + def __init__(self,client_id,client_secret,token_file): + self.session = requests.session() + self.request_token_url = 'https://api.dropbox.com/1/oauth/request_token' + self.authorize_url = 'https://www.dropbox.com/1/oauth/authorize' + self.access_token_url = 'https://api.dropbox.com/1/oauth/access_token' + self.key = '2eoegx5n62z1qyh' + self.secret = '9gsfezp3hc1xl44' + self.client_id = client_id + self.client_secret = client_secret + self.token_file = token_file + self.access_token = None + self.refresh_token = None + if os.path.exists(token_file): + f = open(token_file,'r') + text = f.read() + f.close() + try: + data = json.loads(text) + self.oauth_token = data['oauth_token'] + self.oauth_token_secret = data['oauth_token_secret'] + except Exception as e: + print('Error') + print(e) + + def get_request_token(self): + params = {} + params['oauth_consumer_key'] = KEY + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = '%s&'%SECRET + response = self.session.request('POST',self.request_token_url,params=params) + if response.status_code == 200: + oauth_token_secret, oauth_token = response.text.split('&') + oauth_token_secret = oauth_token_secret.split('=')[1] + self.ts = oauth_token_secret + oauth_token = oauth_token.split('=')[1] + return oauth_token, oauth_token_secret + return None + + def get_authorize_url(self,oauth_token,oauth_token_secret): + params = {} + params['oauth_token'] = oauth_token + params['oauth_callback'] = 'http://localhost' + return 'https://www.dropbox.com/1/oauth/authorize?%s'%(urlencode(params)) + + def get_access_token(self,oauth_token,secret): + params = {} + params['oauth_consumer_key'] = KEY + params['oauth_token'] = oauth_token + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = '%s&%s'%(SECRET,secret) + response = self.session.request('POST',self.access_token_url,params=params) + print(response,response.status_code,response.text) + if response.status_code == 200: + oauth_token_secret, oauth_token,uid = response.text.split('&') + oauth_token_secret = oauth_token_secret.split('=')[1] + oauth_token = oauth_token.split('=')[1] + uid = uid.split('=')[1] + self.oauth_token = oauth_token + self.oauth_token_secret = oauth_token_secret + f = open(self.token_file,'w') + f.write(json.dumps({'oauth_token':oauth_token,'oauth_token_secret':oauth_token_secret})) + f.close() + + return uid, oauth_token, oauth_token_secret + return None + + def get_account_info(self): + ans = self.__do_request('GET','https://api.dropbox.com/1/account/info') + if ans.status_code == 200: + print(ans.text) + + def get_file(self,afile): + url = 'https://api-content.dropbox.com/1/files/sandbox/%s'%(afile) + ans = self.__do_request('GET',url) + if ans.status_code == 200: + print(ans.text) + + def put_file(self,afile): + name = afile.split('/')[-1] + print(name) + url = 'https://api-content.dropbox.com/1/files_put/sandbox/%s'%(name) + print(url) + addparams = {} + addparams['overwrite'] = True + afilee = open(afile,'rb') + data = afilee.read() + afilee.close() + addheaders={'Content-type':'multipart/related; boundary="END_OF_PART"','Content-length':str(len(data)),'MIME-version':'1.0'} + ans = self.__do_request('POST',url, addheaders = addheaders,addparams=addparams, data=data) + if ans is not None: + return ans.text + + def __do_request(self,method,url,addheaders=None,data=None,addparams=None,first=True,files=None): + params = {} + params['oauth_consumer_key'] = KEY + params['oauth_token'] = self.oauth_token + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = '%s&%s'%(SECRET,self.oauth_token_secret) + headers = None + if headers is not None: + headers.update(addheaders) + else: + headers = addheaders + if addparams is not None: + params.update(addparams) + if data: + response = self.session.request(method,url,data=data,headers=headers,params=params,files = files) + else: + response = self.session.request(method,url,headers=headers,params=params,files=files) + print(response,response.status_code) + if response.status_code == 200 or response.status_code == 201: + return response + elif (response.status_code == 401 or response.status_code == 403) and first: + ''' + ans = self.do_refresh_authorization() + if ans: + return self.__do_request(method,url,addheaders,data,params,first=False) + ''' + return None + +UBUNTU_CONSUMER_KEY = 'ubuntuone' +UBUNTU_CONSUMER_SECRET = 'hammertime' + +class UbuntuOneService(object): + def __init__(self, token_file): + self.session = requests.session() + self.request_token_url = 'https://one.ubuntu.com/oauth/request/' + self.authorize_url = 'https://one.ubuntu.com/oauth/authorize/' + self.access_token_url = 'https://one.ubuntu.com/oauth/access/' + self.token_file = token_file + self.access_token = None + self.refresh_token = None + if os.path.exists(token_file): + f = open(token_file,'r') + text = f.read() + f.close() + try: + data = json.loads(text) + self.oauth_token = data['oauth_token'] + self.oauth_token_secret = data['oauth_token_secret'] + except Exception as e: + print('Error') + print(e) + + def get_request_token(self): + params = {} + params['oauth_consumer_key'] = UBUNTU_CONSUMER_KEY + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = 'hammertime%26' + response = self.session.request('POST',self.request_token_url,params=params) + print(response) + if response.status_code == 200: + oauth_token_secret, oauth_token = response.text.split('&') + oauth_token_secret = oauth_token_secret.split('=')[1] + self.ts = oauth_token_secret + oauth_token = oauth_token.split('=')[1] + return oauth_token, oauth_token_secret + return None + + def get_authorize_url(self,oauth_token,oauth_token_secret): + params = {} + params['oauth_token'] = oauth_token + params['oauth_callback'] = 'http://localhost' + return 'https://www.dropbox.com/1/oauth/authorize?%s'%(urlencode(params)) + + def get_access_token(self,oauth_token,secret): + params = {} + params['Oauth realm'] = '' + params['oauth_consumer_key'] = UBUNTU_CONSUMER_KEY + params['oauth_token'] = oauth_token + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = '%s&%s'%(UBUNTU_CONSUMER_SECRET,secret) + params['oauth_callback'] = 'http://localhost:8801/index.cfm/general/getAccessToken' + response = self.session.request('POST',self.access_token_url,params=params) + print(response,response.status_code,response.text) + if response.status_code == 200: + oauth_token_secret, oauth_token,uid = response.text.split('&') + oauth_token_secret = oauth_token_secret.split('=')[1] + oauth_token = oauth_token.split('=')[1] + uid = uid.split('=')[1] + self.oauth_token = oauth_token + self.oauth_token_secret = oauth_token_secret + f = open(self.token_file,'w') + f.write(json.dumps({'oauth_token':oauth_token,'oauth_token_secret':oauth_token_secret})) + f.close() + + return uid, oauth_token, oauth_token_secret + return None + + def get_account_info(self): + ans = self.__do_request('GET','https://api.dropbox.com/1/account/info') + if ans.status_code == 200: + print(ans.text) + + def get_file(self,afile): + url = 'https://api-content.dropbox.com/1/files/dropbox/%s'%(afile) + ans = self.__do_request('GET',url) + if ans.status_code == 200: + print(ans.text) + + def __do_request(self,method,url,addheaders=None,data=None,params=None,first=True,files=None): + params = {} + params['oauth_consumer_key'] = UBUNTU_CONSUMER_KEY + params['oauth_token'] = self.oauth_token + params['oauth_timestamp'] = int(time.time()) + params['oauth_nonce'] = ''.join([str(random.randint(0, 9)) for i in range(8)]) + params['oauth_version'] = '1.0' + params['oauth_signature_method'] = 'PLAINTEXT' + params['oauth_signature'] = '%s&%s'%(UBUNTU_CONSUMER_SECRET,self.oauth_token_secret) + headers = None + if addheaders: + headers.update(addheaders) + if data: + if params: + response = self.session.request(method,url,data=data,headers=headers,params=params,files=files) + else: + response = self.session.request(method,url,data=data,headers=headers,files=files) + else: + if params: + response = self.session.request(method,url,headers=headers,params=params,files=files) + else: + response = self.session.request(method,url,headers=headers,files=files) + print(response,response.status_code) + if response.status_code == 200 or response.status_code == 201: + return response + elif (response.status_code == 401 or response.status_code == 403) and first: + ''' + ans = self.do_refresh_authorization() + if ans: + return self.__do_request(method,url,addheaders,data,params,first=False) + ''' + return None + +class GoogleService(object): + def __init__(self,auth_url,token_url,redirect_uri,scope,client_id,client_secret,token_file): + self.session = requests.session() + self.auth_url = auth_url + self.token_url = token_url + self.redirect_uri = redirect_uri + self.scope = scope + self.client_id = client_id + self.client_secret = client_secret + self.token_file = token_file + self.access_token = None + self.refresh_token = None + if os.path.exists(token_file): + f = open(token_file,'r') + text = f.read() + f.close() + try: + data = json.loads(text) + self.access_token = data['access_token'] + self.refresh_token = data['refresh_token'] + except Exception as e: + print('Error') + print(e) + + def get_authorize_url(self): + oauth_params = {'redirect_uri': self.redirect_uri, 'client_id': self.client_id, 'scope': self.scope, 'response_type':'code'} + authorize_url = "%s?%s" % (self.auth_url, urlencode(oauth_params)) + print('Authorization url: %s'%authorize_url) + return authorize_url + + def get_authorization(self,temporary_token): + data = {'redirect_uri': self.redirect_uri, 'client_id': self.client_id, 'client_secret': self.client_secret, 'code': temporary_token,'grant_type':'authorization_code','scope':self.scope} + response = self.session.request('POST',self.token_url,data=data) + if response.status_code == 200: + ans = json.loads(response.text) + self.access_token = ans['access_token'] + self.refresh_token = ans['refresh_token'] + f = open(self.token_file,'w') + f.write(json.dumps({'access_token':self.access_token,'refresh_token':self.refresh_token})) + f.close() + print('Authorizate') + return self.access_token, self.refresh_token + return None + + def do_revoke_authorization(self): + self.access_token = None + self.refresh_token = None + if os.path.exists(self.token_file): + os.remove(self.token_file) + + def do_refresh_authorization(self): + data = {'client_id': self.client_id, 'client_secret': self.client_secret,'refresh_token': self.refresh_token,'grant_type':'refresh_token'} + response = self.session.request('POST',self.token_url,data=data) + if response.status_code == 200: + ans = json.loads(response.text) + self.access_token = ans['access_token'] + f = open(self.token_file,'w') + f.write(json.dumps({'access_token':self.access_token,'refresh_token':self.refresh_token})) + f.close() + print('Refresh Authorization') + return self.access_token + return None + + def do_request(self,method,url,addheaders,data=None,params=None,first=True): + headers ={'Authorization':'OAuth %s'%self.access_token} + if addheaders: + headers.update(addheaders) + print(headers) + if data: + if params: + response = self.session.request(method,url,data=data,headers=headers,params=params) + else: + response = self.session.request(method,url,data=data,headers=headers) + else: + if params: + response = self.session.request(method,url,headers=headers,params=params) + else: + response = self.session.request(method,url,headers=headers) + print(response) + if response.status_code == 200: + return response + elif response.status_code == 403 and first: + ans = self.do_refresh_authorization() + print(ans) + if ans: + return self.do_request(method,url,addheaders,first=False) + return None +if __name__ == '__main__': + us = UbuntuOneService('tokenus') + session = requests.session() + ans = session.request('GET','https://login.ubuntu.com/') + print(ans) + print(ans.text) + #oauth_token,oauth_token_secret = us.get_request_token() + + + #ds = DropboxService('','','token') + ''' + oauth_token,oauth_token_secret = ds.get_request_token() + authorize_url = ds.get_authorize_url(oauth_token,oauth_token_secret) + ld = LoginDialog(1024,600,authorize_url,'http://localhost/?uid=','not_approved=true') + ld.run() + ans = ld.code + ld.destroy() + if ans is not None: + print(ans) + uid,oauth_token = ans.split('&') + uid = uid.split('=')[1] + oauth_token = oauth_token.split('=')[1] + print(uid,oauth_token) + ans = ds.get_access_token(oauth_token,oauth_token_secret) + print(ans) + print(ds.get_account_info()) + ''' + ''' + print(ds.get_account_info()) + print(ds.get_file('data')) + print(ds.put_file('/home/atareao/Escritorio/data')) + ''' + exit(0) + diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/show_tasks_dialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/show_tasks_dialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/show_tasks_dialog.py 2012-03-11 08:21:06.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/show_tasks_dialog.py 2013-01-19 04:43:44.000000000 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python # -*- coding: iso-8859-15 -*- # __author__='atareao' @@ -25,6 +25,7 @@ # from gi.repository import Gtk, Gdk, GdkPixbuf +from gi.repository import Pango import os import locale @@ -40,7 +41,7 @@ class ShowTasksDialog(Gtk.Dialog): - def __init__(self,gta,tasklist_id): + def __init__(self,tasks,tasklist_id): title = comun.APPNAME + ' | '+_('Show Tasks') Gtk.Dialog.__init__(self,title,None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)) self.set_size_request(450, 300) @@ -62,9 +63,13 @@ hbox.pack_start(scrolledwindow,True,True,0) # # id, text, image - self.store = Gtk.ListStore(str,str) - self.treeview = Gtk.TreeView(model=self.store) - self.treeview.append_column(Gtk.TreeViewColumn('Text', Gtk.CellRendererText(), markup=1)) + self.store = Gtk.ListStore(object) + self.treeview = Gtk.TreeView(model=self.store) + #treeviewcolumn = Gtk.TreeViewColumn('Text', Gtk.CellRendererText(), markup=1) + cellrenderer = Gtk.CellRendererText() + treeviewcolumn = Gtk.TreeViewColumn('Text', cellrenderer) + treeviewcolumn.set_cell_data_func(cellrenderer, self.func) + self.treeview.append_column(treeviewcolumn) scrolledwindow.add(self.treeview) self.treeview.connect('button-press-event',self.on_treeview_button_press_event) # @@ -107,12 +112,23 @@ self.button5.connect('clicked',self.on_button_clear_clicked) vbox2.pack_start(self.button5,False,False,0) # - self.gta = gta + self.tasks = tasks self.tasklist_id = tasklist_id self.offset = 0 self.read_notes() # self.show_all() + + def func(self,column, cell_renderer, tree_model, iter, user_data): + task = tree_model[iter][0] + if task is not None: + cell_renderer.set_property('text', task['title']) + if task['status'] == 'completed': + cell_renderer.set_property('foreground','#FF0000') + cell_renderer.set_property('strikethrough',True) + else: + cell_renderer.set_property('foreground','#000000') + cell_renderer.set_property('strikethrough',False) def on_treeview_button_press_event(self,widget,event): # @@ -124,18 +140,13 @@ if event.button == 1 and event.type == Gdk.EventType(value=5): model,iter = self.treeview.get_selection().get_selected() id = model.get_value(iter,0) - snd = ShowNoteDialog(self.user,id) + snd = TaskDialog(id) snd.run() snd.destroy() - print id def read_notes(self): - for note in self.gta.get_tasks(tasklist_id = self.tasklist_id): - if note['status'] == 'completed': - text = '%s'%note['title'] - else: - text = '%s'%note['title'] - self.store.append([note['id'],text]) + for note in self.tasks.get_tasks(tasklist_id = self.tasklist_id): + self.store.append([note]) def on_button_up_clicked(self,widget): selection = self.treeview.get_selection() @@ -144,21 +155,24 @@ model,iter = selection.get_selected() treepath = model.get_path(iter) path = int(str(treepath)) - id = model.get_value(iter,0) + note = model.get_value(iter,0) if path > 1: - previous_path = Gtk.TreePath.new_from_string(str(path - 2)) + previous_path = Gtk.TreePath.new_from_string(str(path - 1)) previous_iter = model.get_iter(previous_path) - previous_id = model.get_value(previous_iter,0) - note = self.gta.move_task(id, previous_id,tasklist_id = self.tasklist_id) + note_previous = model.get_value(previous_iter,0) + note = self.tasks.move_tasks(note, note_previous) previous_path = Gtk.TreePath.new_from_string(str(path - 1)) + self.store.clear() + self.read_notes() + selection.select_path(previous_path) elif path == 1: previous_path = Gtk.TreePath.new_from_string('0') - note = self.gta.move_task_first(id,tasklist_id = self.tasklist_id) - if previous_path: + previous_iter = model.get_iter(previous_path) + note_previous = model.get_value(previous_iter,0) + note = self.tasks.move_tasks(note, note_previous) self.store.clear() self.read_notes() selection.select_path(previous_path) - def on_button_down_clicked(self,widget): selection = self.treeview.get_selection() @@ -167,34 +181,32 @@ model,iter = selection.get_selected() treepath = model.get_path(iter) path = int(str(treepath)) - id = model.get_value(iter,0) + note = model.get_value(iter,0) iter_next = model.iter_next(iter) if iter_next: path_next = model.get_path(iter_next) - next_id = model.get_value(iter_next,0) - note = self.gta.move_task(id, next_id,tasklist_id = self.tasklist_id) - if note: - self.store.clear() - self.read_notes() - selection.select_path(path_next) + note_next = model.get_value(iter_next,0) + self.tasks.move_tasks(note,note_next) + self.store.clear() + self.read_notes() + selection.select_path(path_next) def on_button_completed_clicked(self,widget): selection = self.treeview.get_selection() if selection: model,iter = selection.get_selected() path = model.get_path(iter) - id = model.get_value(iter,0) - note = self.gta.get_task(id, tasklist_id = self.tasklist_id) + note = model.get_value(iter,0) if note['status'] == 'completed': - self.gta.edit_task(id,tasklist_id = self.tasklist_id,iscompleted = False) + note.set_completed(False) else: - self.gta.edit_task(id,tasklist_id = self.tasklist_id,iscompleted = True) + note.set_completed(True) self.store.clear() self.read_notes() selection.select_path(path) def on_button_clear_clicked(self,widget): - self.gta.clear_completed_tasks(tasklist_id = self.tasklist_id) + self.tasks.clear_completed_tasks(tasklist_id = self.tasklist_id) selection = self.treeview.get_selection() if selection: model,iter = selection.get_selected() @@ -210,30 +222,26 @@ if selection: model,iter = selection.get_selected() path = model.get_path(iter) - id = model.get_value(iter,0) - task = self.gta.get_task(id, tasklist_id = self.tasklist_id) - p = TaskDialog(task = task) + atask = model.get_value(iter,0) + p = TaskDialog(task = atask,tasks = self.tasks) if p.run() == Gtk.ResponseType.ACCEPT: - title = p.get_title() - notes = p.get_notes() - completed = p.is_completed() + p.hide() + atask['title'] = p.get_title() + atask['notes'] = p.get_notes() + atask.set_completed(p.is_completed()) due = p.get_due_date() - print title - print notes - print completed - print due - note = self.gta.edit_task(id, tasklist_id = self.tasklist_id, title = title, notes = notes, iscompleted = completed, due = due) - if note: - self.store.clear() - self.read_notes() - selection.select_path(path) + if due is not None: + atask.set_due(due) + self.store.clear() + self.read_notes() + selection.select_path(path) p.destroy() def close_application(self,widget): self.hide() if __name__ == "__main__": - p = ShowNotesDialog() + p = ShowTasksDialog() if p.run() == Gtk.ResponseType.ACCEPT: p.hide() p.destroy() diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/show_taskslists_dialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/show_taskslists_dialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/show_taskslists_dialog.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/show_taskslists_dialog.py 2013-01-19 05:50:28.000000000 +0000 @@ -0,0 +1,133 @@ +#!/usr/bin/python +# -*- coding: iso-8859-15 -*- +# +__author__='atareao' +__date__ ='$19/02/2012$' +# +# +# Copyright (C) 2011,2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# + +from gi.repository import Gtk, Gdk, GdkPixbuf +from gi.repository import Pango +import os + +import locale +import urllib +import gettext +import comun +from task_dialog import TaskDialog +from tasklist_dialog import TaskListDialog + +locale.setlocale(locale.LC_ALL, '') +gettext.bindtextdomain(comun.APP, comun.LANGDIR) +gettext.textdomain(comun.APP) +_ = gettext.gettext + + +class ShowTasksListsDialog(Gtk.Dialog): + def __init__(self,tasks): + title = comun.APPNAME + ' | '+_('Show tasklists') + Gtk.Dialog.__init__(self,title,None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT)) + self.set_size_request(450, 300) + self.set_resizable(False) + self.set_icon_from_file(comun.ICON) + self.connect('destroy', self.close_application) + # + vbox0 = Gtk.VBox(spacing = 5) + vbox0.set_border_width(5) + self.get_content_area().add(vbox0) + # + hbox = Gtk.HBox() + vbox0.pack_start(hbox,True,True,0) + # + scrolledwindow = Gtk.ScrolledWindow() + scrolledwindow.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) + scrolledwindow.set_shadow_type(Gtk.ShadowType.ETCHED_OUT) + scrolledwindow.set_size_request(450,300) + hbox.pack_start(scrolledwindow,True,True,0) + # + # id, text, image + self.store = Gtk.ListStore(object) + self.treeview = Gtk.TreeView(model=self.store) + cellrenderer = Gtk.CellRendererText() + treeviewcolumn = Gtk.TreeViewColumn('Text', cellrenderer) + treeviewcolumn.set_cell_data_func(cellrenderer, self.func) + self.treeview.append_column(treeviewcolumn) + scrolledwindow.add(self.treeview) + # + vbox2 = Gtk.VBox(spacing = 0) + vbox2.set_border_width(5) + hbox.pack_start(vbox2,False,False,0) + # + self.button1 = Gtk.Button() + self.button1.set_size_request(40,40) + self.button1.set_tooltip_text(_('Add')) + self.button1.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_ADD,Gtk.IconSize.BUTTON)) + self.button1.connect('clicked',self.on_button_add_clicked) + vbox2.pack_start(self.button1,False,False,0) + # + self.button2 = Gtk.Button() + self.button2.set_size_request(40,40) + self.button2.set_tooltip_text(_('Remove')) + self.button2.set_image(Gtk.Image.new_from_stock(Gtk.STOCK_REMOVE,Gtk.IconSize.BUTTON)) + self.button2.connect('clicked',self.on_button_remove_clicked) + vbox2.pack_start(self.button2,False,False,0) + # + self.tasks = tasks + self.read_tasklists() + # + self.show_all() + + def func(self,column, cell_renderer, tree_model, iter, user_data): + tasklist = tree_model[iter][0] + if tasklist is not None: + cell_renderer.set_property('text', tasklist['title']) + + def read_tasklists(self): + for tasklist in self.tasks.get_tasklists(): + self.store.append([tasklist]) + + def on_button_add_clicked(self,widget): + tld = TaskListDialog() + if tld.run() == Gtk.ResponseType.ACCEPT: + tld.hide() + newtasklist = self.tasks.create_tasklist(tld.get_title()) + self.store.append([newtasklist]) + tld.destroy() + + def on_button_remove_clicked(self,widget): + selection = self.treeview.get_selection() + if selection: + previous_path = None + model,iter = selection.get_selected() + tasklist = model.get_value(iter,0) + self.tasks.remove_tasklist(tasklist) + model.remove(iter) + + def close_application(self,widget): + self.hide() + +if __name__ == "__main__": + p = ShowTasksDialog() + if p.run() == Gtk.ResponseType.ACCEPT: + p.hide() + p.destroy() + exit(0) + diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/task_dialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/task_dialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/task_dialog.py 2012-03-31 09:19:10.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/task_dialog.py 2012-12-09 09:28:51.000000000 +0000 @@ -1,4 +1,4 @@ -#! /usr/bin/python +#!/usr/bin/python # -*- coding: iso-8859-15 -*- # __author__='atareao' @@ -30,7 +30,7 @@ import comun import datetime from comboboxcalendar import ComboBoxCalendar - +import rfc3339 locale.setlocale(locale.LC_ALL, '') gettext.bindtextdomain(comun.APP, comun.LANGDIR) @@ -38,7 +38,7 @@ _ = gettext.gettext class TaskDialog(Gtk.Dialog): - def __init__(self, task = None): + def __init__(self, task = None,tasks = None): if task == None: dialog_title = comun.APPNAME + ' | '+_('Add new task') else: @@ -53,46 +53,58 @@ vbox0.set_border_width(5) self.get_content_area().add(vbox0) # - table1 = Gtk.Table(rows = 4, columns = 2, homogeneous = False) + table1 = Gtk.Table(rows = 5, columns = 2, homogeneous = False) table1.set_border_width(5) table1.set_col_spacings(5) table1.set_row_spacings(5) vbox0.add(table1) # + label10 = Gtk.Label(_('Task List')+':') + label10.set_alignment(0,.5) + table1.attach(label10,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) + # + self.liststore = Gtk.ListStore(str,str) + self.entry0 = Gtk.ComboBox.new_with_model(model=self.liststore) + renderer_text = Gtk.CellRendererText() + self.entry0.pack_start(renderer_text, True) + self.entry0.add_attribute(renderer_text, "text", 0) + self.entry0.set_active(0) + table1.attach(self.entry0,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) + # label11 = Gtk.Label(_('Title')+':') label11.set_alignment(0,.5) - table1.attach(label11,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) + table1.attach(label11,0,1,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) # label12 = Gtk.Label(_('Notes')+':') label12.set_alignment(0,0) - table1.attach(label12,0,1,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) + table1.attach(label12,0,1,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) # label13 = Gtk.Label(_('Completed')+':') label13.set_alignment(0,.5) - table1.attach(label13,0,1,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + table1.attach(label13,0,1,3,4, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) # label14 = Gtk.Label(_('Date due')+':') label14.set_alignment(0,0) - table1.attach(label14,0,1,3,4, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) + table1.attach(label14,0,1,4,5, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.SHRINK) # self.entry1 = Gtk.Entry() self.entry1.set_width_chars(60) - table1.attach(self.entry1,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) + table1.attach(self.entry1,1,2,1,2, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) # scrolledwindow2 = Gtk.ScrolledWindow() scrolledwindow2.set_policy(Gtk.PolicyType.AUTOMATIC, Gtk.PolicyType.AUTOMATIC) scrolledwindow2.set_shadow_type(Gtk.ShadowType.ETCHED_OUT) - table1.attach(scrolledwindow2,1,2,1,2, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) + table1.attach(scrolledwindow2,1,2,2,3, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) self.entry2 = Gtk.TextView() self.entry2.set_wrap_mode(Gtk.WrapMode.WORD) scrolledwindow2.set_size_request(350,150) scrolledwindow2.add(self.entry2) # self.entry3 = Gtk.Switch() - table1.attach(self.entry3,1,2,2,3, xoptions = Gtk.AttachOptions.SHRINK, yoptions = Gtk.AttachOptions.SHRINK) + table1.attach(self.entry3,1,2,3,4, xoptions = Gtk.AttachOptions.SHRINK, yoptions = Gtk.AttachOptions.SHRINK) # hbox = Gtk.HBox() - table1.attach(hbox,1,2,3,4, xoptions = Gtk.AttachOptions.SHRINK, yoptions = Gtk.AttachOptions.SHRINK) + table1.attach(hbox,1,2,4,5, xoptions = Gtk.AttachOptions.SHRINK, yoptions = Gtk.AttachOptions.SHRINK) self.entry4 = Gtk.CheckButton() self.entry4.connect('toggled', self.toggle_clicked ) hbox.pack_start(self.entry4,0,0,0) @@ -101,20 +113,28 @@ hbox.pack_start(self.entry5,0,0,0) #table1.attach(self.entry4,1,2,3,4, xoptions = Gtk.AttachOptions.SHRINK, yoptions = Gtk.AttachOptions.SHRINK) # - if task != None: - print task.keys() + if tasks is not None: + for tasklist in tasks.tasklists.values(): + self.liststore.append([tasklist['title'],tasklist['id']]) + if task is not None: + for i,item in enumerate(self.liststore): + if task['tasklist_id'] == item[1]: + self.entry0.set_active(i) + break + self.entry0.set_active(False) if 'title' in task.keys(): self.entry1.set_text(task['title']) - if 'notes' in task.keys(): + if 'notes' in task.keys() and task['notes'] is not None: self.entry2.get_buffer().set_text(task['notes']) if 'status' in task.keys(): self.entry3.set_active(task['status'] == 'completed') - if 'due' in task.keys(): + if 'due' in task.keys() and task['due'] is not None: self.entry4.set_active(True) - print task['due'] - self.entry5.set_date(task['due']) + self.entry5.set_date(rfc3339.parse_datetime(task['due'])) else: self.entry4.set_active(False) + else: + self.entry0.set_active(0) self.show_all() def toggle_clicked(self,widget): @@ -123,6 +143,11 @@ def close_application(self,widget): self.ok = False + def get_tasklist_id(self): + tree_iter = self.entry0.get_active_iter() + model = self.entry0.get_model() + return model[tree_iter][1] + def get_title(self): return self.entry1.get_text() @@ -147,7 +172,7 @@ p.entry5.set_date('2012-03-09T00:00:00.000Z') if p.run() == Gtk.ResponseType.ACCEPT: p.hide() - print p.get_due_date() + print(p.get_due_date()) p.destroy() exit(0) diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/tasklist_dialog.py google-tasks-indicator-0.0.5.1.quantal.1/src/tasklist_dialog.py --- google-tasks-indicator-0.0.3.2~quantal/src/tasklist_dialog.py 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/tasklist_dialog.py 2012-12-09 09:29:31.000000000 +0000 @@ -0,0 +1,85 @@ +#!/usr/bin/python +# -*- coding: iso-8859-15 -*- +# +__author__='atareao' +__date__ ='$19/02/2012$' +# +# +# Copyright (C) 2011,2012 Lorenzo Carbonell +# lorenzo.carbonell.cerezo@gmail.com +# +# 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 . +# +# +# + +from gi.repository import Gtk +import locale +import gettext +import comun + +locale.setlocale(locale.LC_ALL, '') +gettext.bindtextdomain(comun.APP, comun.LANGDIR) +gettext.textdomain(comun.APP) +_ = gettext.gettext + +class TaskListDialog(Gtk.Dialog): + def __init__(self, tasklist = None): + if tasklist == None: + dialog_title = comun.APPNAME + ' | '+_('Add new tasklist') + else: + dialog_title = comun.APPNAME + ' | '+_('Edit tasklist') + Gtk.Dialog.__init__(self,dialog_title,None,Gtk.DialogFlags.MODAL | Gtk.DialogFlags.DESTROY_WITH_PARENT,(Gtk.STOCK_OK, Gtk.ResponseType.ACCEPT,Gtk.STOCK_CANCEL,Gtk.ResponseType.CANCEL)) + self.set_size_request(200, 80) + self.set_resizable(False) + self.set_icon_from_file(comun.ICON) + # + vbox0 = Gtk.VBox(spacing = 5) + vbox0.set_border_width(5) + self.get_content_area().add(vbox0) + # + table1 = Gtk.Table(rows = 1, columns = 2, homogeneous = False) + table1.set_border_width(5) + table1.set_col_spacings(5) + table1.set_row_spacings(5) + vbox0.add(table1) + # + label11 = Gtk.Label(_('Title')+':') + label11.set_alignment(0,.5) + table1.attach(label11,0,1,0,1, xoptions = Gtk.AttachOptions.FILL, yoptions = Gtk.AttachOptions.FILL) + # + self.entry1 = Gtk.Entry() + self.entry1.set_width_chars(60) + table1.attach(self.entry1,1,2,0,1, xoptions = Gtk.AttachOptions.EXPAND, yoptions = Gtk.AttachOptions.SHRINK) + # + if tasklist is not None: + print(task.keys()) + if 'title' in tasklist.keys(): + self.entry1.set_text(tasklist['title']) + self.show_all() + + + def get_title(self): + return self.entry1.get_text() + + + +if __name__ == "__main__": + p = TaskListDialog() + if p.run() == Gtk.ResponseType.ACCEPT: + p.hide() + print(p.get_title()) + p.destroy() + exit(0) + diff -Nru google-tasks-indicator-0.0.3.2~quantal/src/uritemplate/__init__.py google-tasks-indicator-0.0.5.1.quantal.1/src/uritemplate/__init__.py --- google-tasks-indicator-0.0.3.2~quantal/src/uritemplate/__init__.py 2012-03-03 19:08:46.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/src/uritemplate/__init__.py 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -# Early, and incomplete implementation of -04. -# -import re -import urllib - -RESERVED = ":/?#[]@!$&'()*+,;=" -OPERATOR = "+./;?|!@" -EXPLODE = "*+" -MODIFIER = ":^" -TEMPLATE = re.compile(r"{(?P[\+\./;\?|!@])?(?P[^}]+)}", re.UNICODE) -VAR = re.compile(r"^(?P[^=\+\*:\^]+)((?P[\+\*])|(?P[:\^]-?[0-9]+))?(=(?P.*))?$", re.UNICODE) - -def _tostring(varname, value, explode, operator, safe=""): - if type(value) == type([]): - if explode == "+": - return ",".join([varname + "." + urllib.quote(x, safe) for x in value]) - else: - return ",".join([urllib.quote(x, safe) for x in value]) - if type(value) == type({}): - keys = value.keys() - keys.sort() - if explode == "+": - return ",".join([varname + "." + urllib.quote(key, safe) + "," + urllib.quote(value[key], safe) for key in keys]) - else: - return ",".join([urllib.quote(key, safe) + "," + urllib.quote(value[key], safe) for key in keys]) - else: - return urllib.quote(value, safe) - - -def _tostring_path(varname, value, explode, operator, safe=""): - joiner = operator - if type(value) == type([]): - if explode == "+": - return joiner.join([varname + "." + urllib.quote(x, safe) for x in value]) - elif explode == "*": - return joiner.join([urllib.quote(x, safe) for x in value]) - else: - return ",".join([urllib.quote(x, safe) for x in value]) - elif type(value) == type({}): - keys = value.keys() - keys.sort() - if explode == "+": - return joiner.join([varname + "." + urllib.quote(key, safe) + joiner + urllib.quote(value[key], safe) for key in keys]) - elif explode == "*": - return joiner.join([urllib.quote(key, safe) + joiner + urllib.quote(value[key], safe) for key in keys]) - else: - return ",".join([urllib.quote(key, safe) + "," + urllib.quote(value[key], safe) for key in keys]) - else: - if value: - return urllib.quote(value, safe) - else: - return "" - -def _tostring_query(varname, value, explode, operator, safe=""): - joiner = operator - varprefix = "" - if operator == "?": - joiner = "&" - varprefix = varname + "=" - if type(value) == type([]): - if 0 == len(value): - return "" - if explode == "+": - return joiner.join([varname + "=" + urllib.quote(x, safe) for x in value]) - elif explode == "*": - return joiner.join([urllib.quote(x, safe) for x in value]) - else: - return varprefix + ",".join([urllib.quote(x, safe) for x in value]) - elif type(value) == type({}): - if 0 == len(value): - return "" - keys = value.keys() - keys.sort() - if explode == "+": - return joiner.join([varname + "." + urllib.quote(key, safe) + "=" + urllib.quote(value[key], safe) for key in keys]) - elif explode == "*": - return joiner.join([urllib.quote(key, safe) + "=" + urllib.quote(value[key], safe) for key in keys]) - else: - return varprefix + ",".join([urllib.quote(key, safe) + "," + urllib.quote(value[key], safe) for key in keys]) - else: - if value: - return varname + "=" + urllib.quote(value, safe) - else: - return varname - -TOSTRING = { - "" : _tostring, - "+": _tostring, - ";": _tostring_query, - "?": _tostring_query, - "/": _tostring_path, - ".": _tostring_path, - } - - -def expand(template, vars): - def _sub(match): - groupdict = match.groupdict() - operator = groupdict.get('operator') - if operator is None: - operator = '' - varlist = groupdict.get('varlist') - - safe = "@" - if operator == '+': - safe = RESERVED - varspecs = varlist.split(",") - varnames = [] - defaults = {} - for varspec in varspecs: - m = VAR.search(varspec) - groupdict = m.groupdict() - varname = groupdict.get('varname') - explode = groupdict.get('explode') - partial = groupdict.get('partial') - default = groupdict.get('default') - if default: - defaults[varname] = default - varnames.append((varname, explode, partial)) - - retval = [] - joiner = operator - prefix = operator - if operator == "+": - prefix = "" - joiner = "," - if operator == "?": - joiner = "&" - if operator == "": - joiner = "," - for varname, explode, partial in varnames: - if varname in vars: - value = vars[varname] - #if not value and (type(value) == type({}) or type(value) == type([])) and varname in defaults: - if not value and value != "" and varname in defaults: - value = defaults[varname] - elif varname in defaults: - value = defaults[varname] - else: - continue - retval.append(TOSTRING[operator](varname, value, explode, operator, safe=safe)) - if "".join(retval): - return prefix + joiner.join(retval) - else: - return "" - - return TEMPLATE.sub(_sub, template) Binary files /tmp/oJtsiPZ8nV/google-tasks-indicator-0.0.3.2~quantal/src/uritemplate/__init__.pyc and /tmp/wXeh3ZOffj/google-tasks-indicator-0.0.5.1.quantal.1/src/uritemplate/__init__.pyc differ diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/.po google-tasks-indicator-0.0.5.1.quantal.1/template1/.po --- google-tasks-indicator-0.0.3.2~quantal/template1/.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/.po 1970-01-01 00:00:00.000000000 +0000 @@ -1,129 +0,0 @@ -# Language translations for PACKAGE package -# Traducciones al español para el paquete PACKAGE. -# Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# atareao , 2012. -# -msgid "" -msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" -"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-02-26 11:10+0100\n" -"Last-Translator: atareao \n" -"Language-Team: Language \n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 -msgid "Show Tasks" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 -msgid "Up" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 -msgid "Down" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 -msgid "Mark as completed" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 -msgid "Edit" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 -msgid "Clear completed tasks" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 -msgid "Refresh" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -msgid "Show all tasks" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 -msgid "Preferences" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 -msgid "Help" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 -msgid "Exit" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 -msgid "Web..." -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 -msgid "Get help online..." -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 -msgid "Translate this application..." -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 -msgid "Report a bug..." -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 -msgid "About" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 -msgid "An indicator for Google Tasks" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/bs.po google-tasks-indicator-0.0.5.1.quantal.1/template1/bs.po --- google-tasks-indicator-0.0.3.2~quantal/template1/bs.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/bs.po 2013-01-19 06:20:23.000000000 +0000 @@ -0,0 +1,313 @@ +# Bosnian translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-05-20 09:44+0000\n" +"Last-Translator: Nenad Čubić \n" +"Language-Team: Bosnian \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: bs\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Dodaj novi zadatak" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Uredi zadatak" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Naslov" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Bilješke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Završeno" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Prikaži Zadatke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Gore" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Dole" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Označi kao završeno" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Uredi" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Očisti završene zadatke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Prikaži Zadatke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Osvježi" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Prikaži sve zadatke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Postavke" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Pomoć" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Izlaz" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Web..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Online pomoć..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Prevedi ovu aplikaciju..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Prijavi grešku..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "O" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Indikator za Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opcije" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Automatsko pokretanje" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/ca.po google-tasks-indicator-0.0.5.1.quantal.1/template1/ca.po --- google-tasks-indicator-0.0.3.2~quantal/template1/ca.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/ca.po 2013-01-19 06:20:24.000000000 +0000 @@ -0,0 +1,313 @@ +# Catalan translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-09-04 21:35+0000\n" +"Last-Translator: Climent Cànaves \n" +"Language-Team: Catalan \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ca\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Afegeix nova tasca" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Edita la tasca" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Títol" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notes" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Completada" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Mostra les tasques" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Amunt" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Avall" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Marca com a completada" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Edita" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Neteja les tasques completades" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Mostra les tasques" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Actualitza" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Mostra totes les tasques" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Preferències" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Ajuda" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Surt" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Lloc web..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Aconsegueix ajuda en línia..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Tradueix aquesta aplicació..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Informa d'un error..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "Quant a..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Un indicador per Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opcions" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Inici automàtic" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/cs.po google-tasks-indicator-0.0.5.1.quantal.1/template1/cs.po --- google-tasks-indicator-0.0.3.2~quantal/template1/cs.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/cs.po 2013-01-19 06:20:24.000000000 +0000 @@ -0,0 +1,313 @@ +# Czech translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-04-29 21:12+0000\n" +"Last-Translator: Martin Volf \n" +"Language-Team: Czech \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: cs\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Přidat nový úkol" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Upravit úkol" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Titul" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Poznámky" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Dokončeno" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Plánované dokončení" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Zobraz úkoly" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Nahoru" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Dolů" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Označit jako dokončené" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Upravit" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Vymazat dokončené úkoly" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Zobraz úkoly" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Obnovit" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Zobrazit všechny úkoly" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Nastaveni" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Nápověda" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Konec" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Web..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Získat pomoc online..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Přeložit tuto aplikaci..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Nahlásit chybu..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "O aplikaci" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Indikátor Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Možnosti" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Automatické spuštění" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Odlehčený vzhled" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/de.po google-tasks-indicator-0.0.5.1.quantal.1/template1/de.po --- google-tasks-indicator-0.0.3.2~quantal/template1/de.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/de.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,313 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-18 14:17+0000\n" -"Last-Translator: Dennis Baudys \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-25 13:46+0000\n" +"Last-Translator: Der_Techniker \n" "Language-Team: German \n" -"Language: de\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: de\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Neue Aufgabe hinzufügen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Aufgabe bearbeiten" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "Aufgabenliste" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Bezeichnung" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Anmerkungen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Erledigt" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Fälligkeitsdatum" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "Neue Aufgabenliste hinzufügen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "Aufgabenliste bearbeiten" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" -msgstr "Zeige Aufgaben" +msgstr "Aufgaben anzeigen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" -msgstr "nach oben" +msgstr "Hoch" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" -msgstr "nach unten" +msgstr "Runter" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" -msgstr "Erledigt" +msgstr "Als erledigt markieren" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Bearbeiten" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" -msgstr "Erledigte entfernen" +msgstr "Erledigte Aufgaben entfernen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Neue Aufgabe" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Aufgaben anzeigen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 -msgid "Refresh" -msgstr "Neu laden" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "Neue Aufgabenliste hinzufügen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 #, fuzzy +msgid "Manage tasklists" +msgstr "Neue Aufgabenliste hinzufügen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Aktualisieren" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Zeige Aufgaben" +msgstr "Alle Aufgaben anzeigen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "Mit Google synchronisieren" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" -msgstr "Einstelliungen" +msgstr "Einstellungen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Hilfe" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" -msgstr "Schließen" +msgstr "Beenden" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." -msgstr "Internet..." +msgstr "Internet ..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." -msgstr "Onlinehilfe..." +msgstr "Hilfe online erhalten …" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Diese Anwendung übersetzen …" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Einen Fehler melden …" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" -msgstr "Info" +msgstr "Über" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" -msgstr "Google-Aufgaben-Anzeiger" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Aufgabe bearbeiten" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Bezeichnung" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Anmerkungen" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Erledigt" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Fälligkeitsdatum" +msgstr "Ein Indikator für Google-Aufgaben" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 msgid "Options" -msgstr "Optionen:" +msgstr "Optionen" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" -msgstr "" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 msgid "Autostart" msgstr "Automatisch starten" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 msgid "Theme light" -msgstr "Thema light" +msgstr "\"Light\"-Thema" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "Sync-Einstellungen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "Nur lokale Aufgaben" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "Nach extern kopieren" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "Lokale löschen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Neuer Eintrag" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "Nur externe Aufgaben" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "Nach lokal kopieren" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "Externe löschen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "Lokale und externe Aufgaben" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "Anmeldung" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "Zugriff auf Google-Aufgaben erlauben" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "Alle" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Einträge anzeigen" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "Homepage" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "Auf Twitter folgen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "Auf Google+ folgen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "Auf Facebook folgen" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "Indikator für Google-Aufgaben" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "Indikator für Google-Aufgaben" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/es.po google-tasks-indicator-0.0.5.1.quantal.1/template1/es.po --- google-tasks-indicator-0.0.3.2~quantal/template1/es.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/es.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (C) 2012 THE PACKAGE'S COPYRIGHT HOLDER # This file is distributed under the same license as the PACKAGE package. # atareao , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-14 20:29+0000\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" "Last-Translator: Lorenzo Carbonell \n" "Language-Team: Spanish\n" -"Language: es\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: es\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Añadir nueva tarea" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Editar tarea" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Título" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Completado" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Fecha de conclusión" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Mostrar tareas" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "Arriba" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Abajo" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Marcar completo" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Editar" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Borrar tareas completadas" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Añadir nueva tarea" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Mostrar tareas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Refrescar" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Mostrar tareas" +msgstr "Mostrar todas las tareas" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Preferencias" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Ayuda" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "Salir" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "Web..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "Consigue ayuda en internet" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Ayuda a traducir esta aplicación..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Informa de un error en la aplicación..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "Acerca de..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Un indicador para Google Tasks" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Editar tarea" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opciones" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Título" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Autoarranque" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Notas" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Tema claro" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Completado" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Fecha de conclusión" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "Opciones" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "Autoarranque" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "Tema claro" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Añadir una nueva nota" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Muestra todas las notas" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/fi.po google-tasks-indicator-0.0.5.1.quantal.1/template1/fi.po --- google-tasks-indicator-0.0.3.2~quantal/template1/fi.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/fi.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-14 10:25+0000\n" -"Last-Translator: Jiri Grönroos \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" +"Last-Translator: Lorenzo Carbonell \n" "Language-Team: Finnish \n" -"Language: fi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: fi\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Lisää uusi tehtävä" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Muokkaa tehtävää" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Otsikko" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Tehtävät" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Valmistuneet" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Tavoitepäivämäärä" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Näytä tehtävät" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "Ylös" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Alas" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Merkitse valmiiksi" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Muokkaa" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Tyhjennä valmiit tehtävät" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Lisää uusi tehtävä" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Näytä tehtävät" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Päivitä" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Näytä tehtävät" +msgstr "Näytä kaikki tehtävät" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Asetukset" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Ohje" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "Lopeta" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "Verkossa..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "Hae apua verkosta..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Käännä tämä ohjelma..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Raportoi ongelmasta..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "Tietoja" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Google Tasks -ilmaisin" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Muokkaa tehtävää" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Valinnat" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Otsikko" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Automaattinen käynnistys" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Tehtävät" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Vaalea teema" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Valmistuneet" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Tavoitepäivämäärä" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "Valinnat" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "Automaattinen käynnistys" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "Vaalea teema" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Lisää uusi tehtävä" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Näytä tehtävät" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/fr.po google-tasks-indicator-0.0.5.1.quantal.1/template1/fr.po --- google-tasks-indicator-0.0.3.2~quantal/template1/fr.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/fr.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-14 13:01+0000\n" -"Last-Translator: Éric \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" +"Last-Translator: Lorenzo Carbonell \n" "Language-Team: French \n" -"Language: fr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: fr\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Ajouter une tâche" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Modifier la tâche" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Titre" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notes" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Terminée" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Date limite" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Afficher les tâches" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "Déplacer vers le haut" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Déplacer vers le bas" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Noter comme terminée" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Modifier" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Effacer les tâches terminées" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Ajouter une tâche" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Afficher les tâches" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Actualiser" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Afficher les tâches" +msgstr "Afficher toutes les tâches" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Préférences..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Aide" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "Quitter" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "Sur Internet..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "Obtenir de l'aide en ligne..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Traduire cette application..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Signaler un problème..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "À propos" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Un indicateur pour Google Tasks" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Modifier la tâche" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Paramètres" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Titre" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Lancement automatique" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Notes" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Thème allégé" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Terminée" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Date limite" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "Paramètres" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "Lancement automatique" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "Thème allégé" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Ajouter une note" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Afficher les notes" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/it.po google-tasks-indicator-0.0.5.1.quantal.1/template1/it.po --- google-tasks-indicator-0.0.3.2~quantal/template1/it.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/it.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-04-07 16:06+0000\n" -"Last-Translator: bartokk \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" +"Last-Translator: Lorenzo Carbonell \n" "Language-Team: Italian \n" -"Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-04-16 09:44+0000\n" -"X-Generator: Launchpad (build 15099)\n" +"Language: it\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Aggiungi una nuova Attività" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Modifica attività" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Titolo" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Note" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Completata" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Scadenza" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Mostra Attività" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "Sposta in alto" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Sposta in basso" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Segna come completata" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Modifica" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Elimina attività completate" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Aggiungi una nuova Attività" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Mostra Attività" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Aggiorna" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Mostra Attività" +msgstr "Visualizza tutte le attività" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Preferenze" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Aiuto" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "Esci" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "Web..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "Ottenere aiuto in linea..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Traduci questa applicazione..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Segnalare un problema..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "Informazioni su..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Un indicatore per Google Tasks" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Modifica attività" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opzioni" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Titolo" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Avvio automatico" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Note" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Tema chiaro" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Completata" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Scadenza" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "Opzioni" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "Avvio automatico" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "Tema chiaro" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Aggiungi nuova Nota" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Mostra le Note" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/languages.txt google-tasks-indicator-0.0.5.1.quantal.1/template1/languages.txt --- google-tasks-indicator-0.0.3.2~quantal/template1/languages.txt 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/languages.txt 2013-01-19 06:20:23.000000000 +0000 @@ -1,9 +1,15 @@ -es - -zh_CN it -fi +fr +es +ms +bs tr de +zh_CN +pl +fi +cs +pt_BR +ca ru -fr +pt diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/ms.po google-tasks-indicator-0.0.5.1.quantal.1/template1/ms.po --- google-tasks-indicator-0.0.3.2~quantal/template1/ms.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/ms.po 2013-01-19 06:20:23.000000000 +0000 @@ -0,0 +1,313 @@ +# Malay translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-08-29 12:14+0000\n" +"Last-Translator: abuyop \n" +"Language-Team: Malay \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: ms\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Tambah tugas baru" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Sunting tugas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Tajuk" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Nota" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Selesai" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Tarikh luput" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Papar Tugas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Naik" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Turun" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Tanda sebagai selesai" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Sunting" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Kosongkan tugas yang selesai" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Papar Tugas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Segar semula" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Papar semua tugas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Keutamaan" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Bantuan" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Keluar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Sesawang..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Dapatkan bantuan atas talian..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Terjemah aplikasi ini..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Lapor pepijat..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "Perihal" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Merupakan penunjuk untuk Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Pilihan" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Mula-sendiri" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Tema cerah" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/pl.po google-tasks-indicator-0.0.5.1.quantal.1/template1/pl.po --- google-tasks-indicator-0.0.3.2~quantal/template1/pl.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/pl.po 2013-01-19 06:20:23.000000000 +0000 @@ -0,0 +1,313 @@ +# Polish translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-06-10 14:04+0000\n" +"Last-Translator: Michał Boś \n" +"Language-Team: Polish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pl\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Dodaj nowe zadanie" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Modyfikuj zadanie" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Tytuł" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Uwagi" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Ukończone" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Data" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Pokaż zadania" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Wyżej" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Niżej" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Oznacz jako wykonane" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Edytuj" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Wyczyść ukończone zadania" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Pokaż zadania" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Odśwież" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Pokaż wszystkie zadania" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Preferencje" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Pomoc" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Zakończ" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Sieć..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Uzyskaj pomoc w sieci..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Przetłumacz ten program..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Zgłoś błąd..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "O programie" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Aplet dla Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Ustawienia" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Uruchamiaj automatycznie" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Jasny motyw" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/pt.po google-tasks-indicator-0.0.5.1.quantal.1/template1/pt.po --- google-tasks-indicator-0.0.3.2~quantal/template1/pt.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/pt.po 2013-01-19 06:20:24.000000000 +0000 @@ -0,0 +1,313 @@ +# Portuguese translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-08-02 13:26+0000\n" +"Last-Translator: Claudio Novais \n" +"Language-Team: Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Adicionar nova tarefa" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Editar tarefa" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Título" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Concluído" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Data para conclusão" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Mostrar Tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Subir" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Descer" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Marcar como concluída" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Editar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Limpar tarefas concluídas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Mostrar Tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Actualizar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Mostrar todas as tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Definições" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Ajuda" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Sair" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Web" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Obtenha ajuda online..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Traduza este aplicativo..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Relatar uma falha" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "Sobre" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Um indicador para o Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opções" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Arranque automático" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Tema claro" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/pt_BR.po google-tasks-indicator-0.0.5.1.quantal.1/template1/pt_BR.po --- google-tasks-indicator-0.0.3.2~quantal/template1/pt_BR.po 1970-01-01 00:00:00.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/pt_BR.po 2013-01-19 06:20:24.000000000 +0000 @@ -0,0 +1,313 @@ +# Brazilian Portuguese translation for google-tasks-indicator +# Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 +# This file is distributed under the same license as the google-tasks-indicator package. +# FIRST AUTHOR , 2012. +# +msgid "" +msgstr "" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" +"Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-08-03 00:51+0000\n" +"Last-Translator: Marcelo Messias \n" +"Language-Team: Brazilian Portuguese \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"Language: pt_BR\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Adicionar nova tarefa" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Editar tarefa" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Título" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Concluída" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Data Definida" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 +msgid "Show Tasks" +msgstr "Mostrar Tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 +msgid "Up" +msgstr "Para cima" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 +msgid "Down" +msgstr "Para baixo" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 +msgid "Mark as completed" +msgstr "Marcar como concluída" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 +msgid "Edit" +msgstr "Editar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 +msgid "Clear completed tasks" +msgstr "Limpar tarefas concluídas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Mostrar Tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 +msgid "Refresh" +msgstr "Atualizar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 +msgid "Show all tasks" +msgstr "Mostrar todas as tarefas" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 +msgid "Preferences" +msgstr "Configurações" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 +msgid "Help" +msgstr "Ajuda" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 +msgid "Exit" +msgstr "Sair" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 +msgid "Web..." +msgstr "Web..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 +msgid "Get help online..." +msgstr "Obter ajuda online..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 +msgid "Translate this application..." +msgstr "Traduzir este aplicativo..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 +msgid "Report a bug..." +msgstr "Relatar uma falha..." + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 +msgid "About" +msgstr "Sobre" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 +msgid "An indicator for Google Tasks" +msgstr "Um indicador para o Google Tasks" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Opções" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Inicialização automática" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Tema Light" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/ru.po google-tasks-indicator-0.0.5.1.quantal.1/template1/ru.po --- google-tasks-indicator-0.0.3.2~quantal/template1/ru.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/ru.po 2013-01-19 06:20:24.000000000 +0000 @@ -2,136 +2,315 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-14 12:54+0000\n" -"Last-Translator: Alex Tr \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-17 19:02+0000\n" +"Last-Translator: dr&mx \n" "Language-Team: Russian \n" -"Language: ru\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: ru\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Добавить задачу" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Редактировать задачу" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "Список задач" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Заголовок" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Заметки" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Выполнено" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Установленный срок" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "Добавить новый список задач" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "Редактировать список задач" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Показать задачи" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" -msgstr "Вверх" +msgstr "Верх" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Вниз" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Отметить как выполненное" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" -msgstr "Изменить" +msgstr "Редактировать" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Очистить завершенные задачи" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Добавить задачу" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Показать задачи" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" +"Вы должны разрешить индикатору управлять календарём Google.\n" +" Вы хотите разрешить?" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "Добавить новый список задач" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +#, fuzzy +msgid "Manage tasklists" +msgstr "Добавить новый список задач" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Обновить" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Показать задачи" +msgstr "Показать все задачи" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "Синхронизировать с Google" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Параметры" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" -msgstr "Справка" +msgstr "Помощь" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" -msgstr "Выход" +msgstr "Выйти" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." -msgstr "Веб-сайт" +msgstr "Веб-сайт..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." -msgstr "Помощь онлайн" +msgstr "Помощь онлайн..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." -msgstr "Перевести это приложение" +msgstr "Перевод этого приложения..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." -msgstr "Сообщить об ошибке" +msgstr "Сообщить об ошибке..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "О программе" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Индикатор задач Google" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Изменить задачу" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Название" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Заметки" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Выполнено" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Дата:" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 msgid "Options" -msgstr "Параметры" - -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" -msgstr "" +msgstr "Настройки" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 msgid "Autostart" msgstr "Автозапуск" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 msgid "Theme light" msgstr "Светлая иконка" -#~ msgid "Add new Note" -#~ msgstr "Добавить задачу" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "Настройки синхронизации" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "Задачи только у себя" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "Копировать на сервер" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" +msgstr "Удалять у себя" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "Без изменений" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "Задачи только на сервере" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "Копировать к себе" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "Удалять на сервере" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "Задачи у себя и на сервере" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "Войти" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "Разрешить доступ к задачам Google" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "Все" -#~ msgid "Show Notes" -#~ msgstr "Показать заметки" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "Вы должны дать доступ индикатору к задачам Google?" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "В начало" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "Мы в Twitter" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "Мы в Google+" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "Мы в Facebook" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "Индикатор задачи Google" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "Индикатор задач Google" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/template1.pot google-tasks-indicator-0.0.5.1.quantal.1/template1/template1.pot --- google-tasks-indicator-0.0.3.2~quantal/template1/template1.pot 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/template1.pot 2013-01-19 06:20:23.000000000 +0000 @@ -8,7 +8,7 @@ msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,113 +17,296 @@ "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +msgid "Show tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google " +"Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/tr.po google-tasks-indicator-0.0.5.1.quantal.1/template1/tr.po --- google-tasks-indicator-0.0.3.2~quantal/template1/tr.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/tr.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-24 01:04+0000\n" -"Last-Translator: Şâkir Aşçı \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" +"Last-Translator: Lorenzo Carbonell \n" "Language-Team: Turkish \n" -"Language: tr\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: tr\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "Yeni görev ekle" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "Görevi düzenle" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "Başlık" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "Notlar" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "Tamamlanan Görevler" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "Bitiş târihi" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "Görevleri Göster" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "Yukarı" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "Aşağı" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "Tamamlanmış olarak işâretle" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "Düzenle" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "Tamamlanan görevleri temizle" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "Yeni görev ekle" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "Görevleri Göster" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "Yenile" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "Görevleri Göster" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "Ayarlar" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "Yardım" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "Çıkış" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "Genelağ..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "Çevrimiçi yardım al..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "Bu uygulamanın çevirisini yap..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "Hatâ bildir...." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "Hakkında" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Google Görevleri göstergesi" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "Görevi düzenle" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "Seçenekler" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "Başlık" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "Özişler Başla" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "Notlar" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "Arayüz ışığı" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "Tamamlanan Görevler" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "Bitiş târihi" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "Seçenekler" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "Özişler Başla" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "Arayüz ışığı" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "Yeni Not Ekle" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "Notları Göster" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/template1/zh_CN.po google-tasks-indicator-0.0.5.1.quantal.1/template1/zh_CN.po --- google-tasks-indicator-0.0.3.2~quantal/template1/zh_CN.po 2012-04-16 09:47:11.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/template1/zh_CN.po 2013-01-19 06:20:23.000000000 +0000 @@ -2,136 +2,312 @@ # Copyright (c) 2012 Rosetta Contributors and Canonical Ltd 2012 # This file is distributed under the same license as the google-tasks-indicator package. # FIRST AUTHOR , 2012. -# +# msgid "" msgstr "" -"Project-Id-Version: google-tasks-indicator 0.0.3.1\n" +"Project-Id-Version: google-tasks-indicator 0.0.5.1.quantal.1\n" "Report-Msgid-Bugs-To: lorenzo.carbonell.cerezo@gmail.com\n" -"POT-Creation-Date: 2012-04-16 11:47+0200\n" -"PO-Revision-Date: 2012-03-15 03:33+0000\n" -"Last-Translator: Wang Dianjin \n" +"POT-Creation-Date: 2013-01-19 07:20+0100\n" +"PO-Revision-Date: 2012-12-07 23:34+0000\n" +"Last-Translator: Lorenzo Carbonell \n" "Language-Team: Chinese (Simplified) \n" -"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2012-03-31 09:32+0000\n" -"X-Generator: Launchpad (build 15032)\n" +"Language: zh_CN\n" +"X-Generator: Launchpad (build 16430)\n" +"X-Launchpad-Export-Date: 2013-01-19 06:00+0000\n" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:309 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:292 +msgid "Add new task" +msgstr "添加新任务" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:45 +msgid "Edit task" +msgstr "编辑任务" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:62 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:68 +msgid "Task List" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:74 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:58 +msgid "Title" +msgstr "标题" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:78 +msgid "Notes" +msgstr "备注" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:82 +msgid "Completed" +msgstr "已完成" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/task_dialog.py:86 +msgid "Date due" +msgstr "截止日期" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:40 +msgid "Add new tasklist" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/tasklist_dialog.py:42 +msgid "Edit tasklist" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:45 msgid "Show Tasks" msgstr "显示任务" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:77 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:82 msgid "Up" msgstr "上移" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:84 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:89 msgid "Down" msgstr "下移" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:91 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:96 msgid "Mark as completed" msgstr "标记为已完成" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:98 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:103 msgid "Edit" msgstr "编辑" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/show_tasks_dialog.py:105 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:155 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_tasks_dialog.py:110 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:314 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:297 msgid "Clear completed tasks" msgstr "清除已完成的任务" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:152 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:43 -msgid "Add new task" -msgstr "添加新任务" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:46 +#, fuzzy +msgid "Show tasklists" +msgstr "显示任务" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:81 +msgid "Add" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/show_taskslists_dialog.py:88 +msgid "Remove" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:169 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:164 +msgid "" +"You have to authorize Google-Tasks-Indicator to manage your Google Calendar.\n" +" Do you want to authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:310 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:294 +msgid "Add new task list" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:154 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:311 +msgid "Manage tasklists" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:313 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:296 msgid "Refresh" msgstr "刷新" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:156 -#, fuzzy +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:315 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:298 msgid "Show all tasks" -msgstr "显示任务" +msgstr "显示所有任务" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:316 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:299 +msgid "Synchronize with Google" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:158 -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:319 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:302 msgid "Preferences" msgstr "首选项" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:160 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:321 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:304 msgid "Help" msgstr "帮助" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:163 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:324 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:307 msgid "Exit" msgstr "退出" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:176 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:332 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:315 msgid "Web..." msgstr "网络..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:177 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:333 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:316 msgid "Get help online..." msgstr "获得在线帮助..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:178 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:334 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:317 msgid "Translate this application..." msgstr "翻译此程序..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:179 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:335 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:318 msgid "Report a bug..." msgstr "报告 Bug..." -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:181 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:337 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:325 msgid "About" msgstr "关于" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/google-tasks-indicator.py:259 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/google-tasks-indicator.py:456 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:453 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:19 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:20 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:21 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:22 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:23 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:24 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:25 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:26 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:42 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:43 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:44 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:45 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:46 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:47 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:48 msgid "An indicator for Google Tasks" msgstr "Google 任务提示器" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:45 -msgid "Edit task" -msgstr "编辑任务" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:61 +msgid "Options" +msgstr "选项" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:62 -msgid "Title" -msgstr "标题" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:80 +msgid "Autostart" +msgstr "开机启动" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:66 -msgid "Notes" -msgstr "备注" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:87 +msgid "Theme light" +msgstr "浅色主题" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:70 -msgid "Completed" -msgstr "已完成" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:95 +msgid "Sync options" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/task_dialog.py:74 -msgid "Date due" -msgstr "截止日期" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:103 +msgid "Tasks local only" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:68 -msgid "Options" -msgstr "选项" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:108 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:130 +msgid "Copy to external" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:75 -msgid "Task list" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:110 +msgid "Delete local" msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:94 -msgid "Autostart" -msgstr "开机启动" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:112 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:124 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:132 +msgid "Do none" +msgstr "" -#: /home/atareao/Dropbox/tp/google-tasks-indicator/src/preferences_dialog.py:101 -msgid "Theme light" -msgstr "浅色主题" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:115 +msgid "Tasks external only" +msgstr "" -#~ msgid "Add new Note" -#~ msgstr "添加新备忘" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:120 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:128 +msgid "Copy to local" +msgstr "" -#~ msgid "Show Notes" -#~ msgstr "显示备忘" +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:122 +msgid "Delete external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:135 +msgid "Tasks local and external" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:141 +msgid "Login" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:149 +msgid "Allow access to Google Tasks" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:195 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:280 +msgid "All" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/preferences_dialog.py:272 +msgid "" +"You have to authorize Google-Task-Indicator to use it, do you want to " +"authorize?" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:320 +msgid "Homepage" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:321 +msgid "Follow us in Twitter" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:322 +msgid "Follow us in Google+" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/src/googletasksindicator.py:323 +msgid "Follow us in Facebook" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:11 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:12 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:13 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:14 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:15 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:16 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:17 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:18 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:35 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:36 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:37 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:38 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:39 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:40 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:41 +msgid "Google-Taks-Indicator" +msgstr "" + +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:27 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:28 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:29 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:30 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:31 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:32 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:33 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:34 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:49 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:50 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:51 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:52 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:53 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:54 +#: /home/atareao/Dropbox/tp/quantal/google-tasks-indicator/Google-Tasks-Indicator.desktop.in:55 +msgid "Google-Tasks-Indicator" +msgstr "" diff -Nru google-tasks-indicator-0.0.3.2~quantal/tools google-tasks-indicator-0.0.5.1.quantal.1/tools --- google-tasks-indicator-0.0.3.2~quantal/tools 2011-09-24 05:14:52.000000000 +0000 +++ google-tasks-indicator-0.0.5.1.quantal.1/tools 1970-01-01 00:00:00.000000000 +0000 @@ -1,297 +0,0 @@ -#! /usr/bin/python -# -*- coding: iso-8859-15 -*- -# -__author__='atareao' -__date__ ='$07/10/2010' -# -# -# -# Copyright (C) 2010 Lorenzo Carbonell -# lorenzo.carbonell.cerezo@gmail.com -# -# 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 . -# -# -# - -import os -import glob -import shlex -import subprocess -import shutil -######################################################################## -def ejecuta(comando): - print ('Ejecutando... %s'%comando) - args = shlex.split(comando) - p = subprocess.Popen(args, bufsize=10000, stdout=subprocess.PIPE) - valor = p.communicate()[0] - return valor -######################################################################## -def list_src(): - file_txt = os.path.join(MAIN_DIR,'files.txt') - f = open(file_txt,'w') - for file in glob.glob(os.path.join(SRC_DIR,'*.py')): - f.write('%s\n'%file) - f.close() - return file_txt - -def list_languages(): - lans = [] - file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') - if os.path.exists(file_txt)==True: - f = open(file_txt,'r') - for linea in f.readlines(): - lan = linea[:-1] - print lan - lans.append(lan) - f.close() - for file in glob.glob(os.path.join(LANGUAGES_DIR,'*.po')): - lan = os.path.splitext(os.path.basename(file))[0] - if lan not in lans: - lans.append(lan) - f = open(file_txt,'w') - for lan in lans: - f.write('%s\n'%lan) - f.close() - return file_txt - -def update_translations(): - file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') - f = open(file_txt,'r') - for file in f.readlines(): - lan = file[:-1] - file = os.path.join(LANGUAGES_DIR,lan+'.po') - print '############################################################' - print lan - print '############################################################' - if os.path.exists(file): - command = 'msgmerge -U %s %s'%(file,TEMPLATE) - else: - command = 'msginit --output-file=%s --input=%s --locale=%s'%(file,TEMPLATE,lan) - print ejecuta(command) - edit_language_file(file) - f.close() - -def edit_language_file(file): - fr = open(file,'r') - file_out = file+'.new' - fs = open(file_out,'w') - for line in fr.readlines(): - if line.find('Project-Id-Version:')!=-1: - line = '"Project-Id-Version: %s %s\\n"\n'%(APP,VERSION) - elif line.find('Content-Type:')!=-1: - line = '"Content-Type: text/plain; charset=UTF-8\\n"\n' - fs.write(line) - fs.close() - fr.close() - shutil.move(file_out,file) - -def remove_security_copies(): - for file in glob.glob(os.path.join(LANGUAGES_DIR,'*.po~')): - os.remove(file) -######################################################################## -def remove_files(dir,ext): - files = [] - for file in glob.glob(os.path.join(dir,'*')): - if file != None and os.path.exists(file): - if os.path.isdir(file): - files.extend(list_files_to_package(file)) - else: - files.append(file) - for file in files: - if os.path.splitext(file)[1] == ext: - os.remove(file) - - -def remove_compiled_files(dir): - remove_files(dir,'.pyc') - -def remove_languages_saved_files(dir): - remove_files(dir,'.po~') - -def create_temporal_file(dir): - temp_file = os.path.join(MAIN_DIR,'temp_files.txt') - f = open(temp_file,'w') - for file in list_files_to_package(dir): - f.write('%s\n'%file) - f.close() - return temp_file - -def create_rules(file): - if os.path.exists(file): - os.remove(file) - f = open(file,'w') - f.write('#!/usr/bin/make -f\n') - f.write('# Sample debian/rules that uses debhelper.\n') - f.write('# This file is public domain software, originally written by Joey Hess.\n') - f.write('#\n') - f.write('# This version is for packages that are architecture independent.\n') - f.write('\n') - f.write('# Uncomment this to turn on verbose mode.\n') - f.write('#export DH_VERBOSE=1\n') - f.write('\n') - f.write('build: build-stamp\n') - f.write('build-stamp:\n') - f.write('\tdh_testdir\n') - f.write('\n') - f.write('\t# Add here commands to compile the package.\n') - f.write('\t#$(MAKE)\n') - f.write('\n') - f.write('\ttouch build-stamp\n') - f.write('\n') - f.write('clean:\n') - f.write('\tdh_testdir\n') - f.write('\tdh_testroot\n') - f.write('\trm -f build-stamp\n') - f.write('\n') - f.write('\t# Add here commands to clean up after the build process.\n') - f.write('\t#$(MAKE) clean\n') - f.write('\t#$(MAKE) distclean\n') - f.write('\n') - f.write('\tdh_clean\n') - f.write('\n') - f.write('install: build\n') - f.write('\tdh_testdir\n') - f.write('\tdh_testroot\n') - f.write('\tdh_prep\n') - f.write('\tdh_installdirs\n') - f.write('\tdh_install\n') - #################################################################### - f.write('\t# Create languages directories\n') - file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') - fl = open(file_txt,'r') - for lan in fl.readlines(): - lan = lan[:-1] - f.write('\tmkdir -p ${CURDIR}/debian/%s/usr/share/locale-langpack/%s/LC_MESSAGES\n'%(APP,lan)) - fl.close() - f.write('\t# End create languages directories\n') - #################################################################### - f.write('\t# Compile languages\n') - file_txt =os.path.join(LANGUAGES_DIR,'languages.txt') - fl = open(file_txt,'r') - for lan in fl.readlines(): - lan = lan[:-1] - f.write('\tmsgfmt template1/%s.po -o ${CURDIR}/debian/%s/usr/share/locale-langpack/%s/LC_MESSAGES/%s.mo\n'%(lan,APP,lan,APP)) - fl.close() - f.write('\t# End comile languages\n') - #################################################################### - f.write('\n') - f.write('\t# Add here commands to install the package into debian/.\n') - f.write('\t#$(MAKE) prefix=`pwd`/debian/`dh_listpackages`/usr install\n') - f.write('\n') - f.write('# Build architecture-independent files here.\n') - f.write('binary-indep: build install\n') - f.write('\tdh_testdir\n') - f.write('\tdh_testroot\n') - f.write('\tdh_installchangelogs\n') - f.write('\tdh_installdocs\n') - f.write('\tdh_installexamples\n') - f.write('\t# added gconf and icons\n') - f.write('\tdh_gconf\n') - f.write('\tdh_icons\n') - f.write('# dh_installmenu\n') - f.write('# dh_installdebconf\n') - f.write('# dh_installlogrotate\n') - f.write('# dh_installemacsen\n') - f.write('# dh_installcatalogs\n') - f.write('# dh_installpam\n') - f.write('# dh_installmime\n') - f.write('# dh_installinit\n') - f.write('# dh_installcron\n') - f.write('# dh_installinfo\n') - f.write('# dh_installwm\n') - f.write('# dh_installudev\n') - f.write('# dh_lintian\n') - f.write('# dh_bugfiles\n') - f.write('# dh_undocumented\n') - f.write('\tdh_installman\n') - f.write('\tdh_link\n') - f.write('\tdh_compress\n') - f.write('\tdh_fixperms\n') - f.write('# dh_perl\n') - f.write('\tdh_pysupport\n') - f.write('\tdh_installdeb\n') - f.write('\tdh_gencontrol\n') - f.write('\tdh_md5sums\n') - f.write('\tdh_builddeb\n') - f.write('\n') - f.write('# Build architecture-dependent files here.\n') - f.write('binary-arch: build install\n') - f.write('# We have nothing to do by default.\n') - f.write('\n') - f.write('binary: binary-indep binary-arch\n') - f.write('.PHONY: build clean binary-indep binary-arch binary install\n') - f.close() - os.chmod(file,0777) - -def delete_it(file): - if os.path.exists(file): - if os.path.isdir(file): - shutil.rmtree(file) - else: - os.remove(file) - -def babilon(): - print '############################################################' - print 'Parent dir -> %s'%MAIN_DIR - print 'Languages dir -> %s'%LANGUAGES_DIR - print 'Source dir -> %s'%SRC_DIR - print '############################################################' - print 'Updating template' - print '############################################################' - files_file = list_src() - command = 'xgettext --msgid-bugs-address=%s --language=Python --keyword=_ --keyword=N_ --output=%s --files-from=%s'%(AUTHOR_EMAIL,TEMPLATE,files_file) - print ejecuta(command) - delete_it(files_file) - print '############################################################' - print 'List languages' - print '############################################################' - # - list_languages() - # - print '############################################################' - print 'Updating translations' - print '############################################################' - update_translations() - print '############################################################' - print 'Removing security copies' - print '############################################################' - remove_security_copies() - -if __name__ == '__main__': - MAIN_DIR = os.getcwd() - DEBIAN_DIR = os.path.join(MAIN_DIR,'debian') - LANGUAGES_DIR = os.path.join(MAIN_DIR,'template1') - SRC_DIR = os.path.join(MAIN_DIR,'src') - TEMPLATE = os.path.join(LANGUAGES_DIR,'template1.pot') - CHANGELOG = os.path.join(DEBIAN_DIR,'changelog') - if os.path.exists(CHANGELOG): - f = open(CHANGELOG,'r') - line = f.readline() - print line - f.close() - pos=line.find('(') - posf=line.find('-',pos) - APP = line[:pos].strip() - VERSION = line[pos+1:posf].strip() - APPNAME = APP.title() - AUTHOR = 'Lorenzo Carbonell' - AUTHOR_EMAIL = 'lorenzo.carbonell.cerezo@gmail.com' - babilon() - rules_file = os.path.join(DEBIAN_DIR,'rules') - if os.path.exists(rules_file): - delete_it(rules_file) - create_rules(rules_file) - print rules_file - exit(0)