summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--3rdparty/miniColors/GPL-LICENSE.txt278
-rw-r--r--3rdparty/miniColors/MIT-LICENSE.txt20
-rwxr-xr-x3rdparty/miniColors/css/images/colors.pngbin0 -> 12485 bytes
-rwxr-xr-x3rdparty/miniColors/css/images/trigger.pngbin0 -> 1406 bytes
-rwxr-xr-x3rdparty/miniColors/css/jquery.miniColors.css81
-rwxr-xr-x3rdparty/miniColors/js/jquery.miniColors.js580
-rwxr-xr-x3rdparty/miniColors/js/jquery.miniColors.min.js9
-rw-r--r--3rdparty/openid/class.openid.v3.php (renamed from apps/user_openid/class.openid.v3.php)0
-rw-r--r--3rdparty/openid/phpmyid.php (renamed from apps/user_openid/phpmyid.php)0
-rw-r--r--apps/calendar/ajax/import/calendarcheck.php18
-rw-r--r--apps/calendar/ajax/import/dialog.php2
-rw-r--r--apps/calendar/ajax/import/dropimport.php89
-rw-r--r--apps/calendar/ajax/import/import.php76
-rw-r--r--apps/calendar/appinfo/app.php3
-rw-r--r--apps/calendar/css/import.css14
-rw-r--r--apps/calendar/js/calendar.js19
-rw-r--r--apps/calendar/js/loader.js214
-rw-r--r--apps/calendar/js/settings.js4
-rw-r--r--apps/calendar/l10n/de.php41
-rw-r--r--apps/calendar/l10n/it.php50
-rw-r--r--apps/calendar/l10n/vi.php135
-rw-r--r--apps/calendar/lib/calendar.php36
-rw-r--r--apps/calendar/lib/connector_sabre.php8
-rw-r--r--apps/calendar/lib/import.php334
-rw-r--r--apps/calendar/templates/part.import.php74
-rw-r--r--apps/contacts/ajax/loadphoto.php46
-rw-r--r--apps/contacts/css/contacts.css9
-rw-r--r--apps/contacts/js/contacts.js433
-rw-r--r--apps/contacts/js/loader.js4
-rw-r--r--apps/contacts/l10n/it.php103
-rw-r--r--apps/contacts/l10n/vi.php48
-rw-r--r--apps/contacts/templates/index.php32
-rw-r--r--apps/files/ajax/newfile.php58
-rw-r--r--apps/files/ajax/scan.php5
-rw-r--r--apps/files/appinfo/update.php11
-rw-r--r--apps/files/appinfo/version2
-rw-r--r--apps/files/js/files.js36
-rw-r--r--apps/files/l10n/es.php14
-rw-r--r--apps/files/l10n/it.php14
-rw-r--r--apps/files/l10n/vi.php31
-rw-r--r--apps/files_imageviewer/js/jquery.fancybox-1.3.4.js4
-rw-r--r--apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js2
-rw-r--r--apps/files_sharing/sharedstorage.php2
-rw-r--r--apps/gallery/l10n/de.php8
-rw-r--r--apps/gallery/l10n/es.php8
-rw-r--r--apps/gallery/l10n/it.php8
-rw-r--r--apps/gallery/l10n/vi.php11
-rw-r--r--apps/media/l10n/vi.php14
-rw-r--r--apps/user_ldap/appinfo/app.php14
-rw-r--r--apps/user_ldap/group_ldap.php94
-rw-r--r--apps/user_ldap/lib/access.php597
-rw-r--r--apps/user_ldap/lib/connection.php255
-rw-r--r--apps/user_ldap/lib_ldap.php721
-rw-r--r--apps/user_ldap/tests/group_ldap.php4
-rw-r--r--apps/user_ldap/user_ldap.php72
-rw-r--r--apps/user_migrate/templates/settings.php2
-rw-r--r--apps/user_openid/user.php2
-rw-r--r--apps/user_openid/user_openid.php2
-rw-r--r--core/ajax/appconfig.php3
-rw-r--r--core/ajax/userlist.php46
-rw-r--r--core/ajax/validateuser.php38
-rw-r--r--core/js/eventsource.js1
-rw-r--r--core/l10n/vi.php64
-rw-r--r--core/templates/layout.user.php1
-rw-r--r--l10n/ar_SA/calendar.po814
-rw-r--r--l10n/ar_SA/contacts.po871
-rw-r--r--l10n/ar_SA/core.po268
-rw-r--r--l10n/ar_SA/files.po198
-rw-r--r--l10n/ar_SA/gallery.po58
-rw-r--r--l10n/ar_SA/media.po66
-rw-r--r--l10n/ar_SA/settings.po206
-rw-r--r--l10n/de/calendar.po411
-rw-r--r--l10n/de/gallery.po66
-rw-r--r--l10n/es/files.po69
-rw-r--r--l10n/es/gallery.po65
-rw-r--r--l10n/es/settings.po63
-rw-r--r--l10n/id_ID/calendar.po814
-rw-r--r--l10n/id_ID/contacts.po871
-rw-r--r--l10n/id_ID/core.po268
-rw-r--r--l10n/id_ID/files.po198
-rw-r--r--l10n/id_ID/gallery.po58
-rw-r--r--l10n/id_ID/media.po66
-rw-r--r--l10n/id_ID/settings.po206
-rw-r--r--l10n/it/calendar.po403
-rw-r--r--l10n/it/contacts.po646
-rw-r--r--l10n/it/files.po68
-rw-r--r--l10n/it/gallery.po64
-rw-r--r--l10n/it/settings.po62
-rw-r--r--l10n/so/calendar.po814
-rw-r--r--l10n/so/contacts.po871
-rw-r--r--l10n/so/core.po268
-rw-r--r--l10n/so/files.po198
-rw-r--r--l10n/so/gallery.po58
-rw-r--r--l10n/so/media.po66
-rw-r--r--l10n/so/settings.po206
-rw-r--r--l10n/templates/bookmarks.pot4
-rw-r--r--l10n/templates/calendar.pot375
-rw-r--r--l10n/templates/contacts.pot561
-rw-r--r--l10n/templates/core.pot34
-rw-r--r--l10n/templates/files.pot40
-rw-r--r--l10n/templates/gallery.pot50
-rw-r--r--l10n/templates/lib.pot112
-rw-r--r--l10n/templates/media.pot4
-rw-r--r--l10n/templates/settings.pot44
-rw-r--r--l10n/vi/calendar.po816
-rw-r--r--l10n/vi/contacts.po872
-rw-r--r--l10n/vi/core.po269
-rw-r--r--l10n/vi/files.po199
-rw-r--r--l10n/vi/gallery.po60
-rw-r--r--l10n/vi/media.po67
-rw-r--r--l10n/vi/settings.po208
-rwxr-xr-xlib/app.php6
-rw-r--r--lib/base.php3
-rw-r--r--lib/cache.php108
-rw-r--r--lib/cache/apc.php5
-rw-r--r--lib/cache/broker.php6
-rw-r--r--lib/cache/file.php5
-rw-r--r--lib/cache/xcache.php5
-rw-r--r--lib/connector/sabre/directory.php22
-rw-r--r--lib/connector/sabre/file.php13
-rw-r--r--lib/connector/sabre/node.php16
-rw-r--r--lib/db.php6
-rw-r--r--lib/eventsource.php3
-rw-r--r--lib/filecache.php32
-rw-r--r--lib/filestorage.php2
-rw-r--r--lib/filestorage/common.php2
-rw-r--r--lib/filesystem.php193
-rw-r--r--lib/filesystemview.php457
-rw-r--r--lib/group.php8
-rw-r--r--lib/group/backend.php2
-rw-r--r--lib/group/interface.php76
-rw-r--r--lib/helper.php57
-rw-r--r--lib/image.php13
-rw-r--r--lib/installer.php30
-rw-r--r--lib/json.php14
-rw-r--r--lib/mimetypes.fixlist.php22
-rw-r--r--lib/mimetypes.list.php13
-rw-r--r--lib/minimizer.php10
-rw-r--r--lib/ocs.php998
-rw-r--r--lib/public/app.php15
-rw-r--r--lib/public/groupinterface.php31
-rw-r--r--lib/public/userinterface.php31
-rw-r--r--lib/public/util.php11
-rw-r--r--lib/user.php12
-rw-r--r--lib/user/backend.php2
-rw-r--r--lib/user/interface.php60
-rwxr-xr-xlib/util.php59
-rw-r--r--ocs/providers.php4
-rw-r--r--remote.php2
-rw-r--r--settings/l10n/es.php7
-rw-r--r--settings/l10n/it.php7
-rw-r--r--settings/l10n/vi.php48
-rw-r--r--tests/lib/cache.php21
-rw-r--r--tests/lib/cache/file.php19
-rw-r--r--webapps.php54
155 files changed, 16861 insertions, 3628 deletions
diff --git a/3rdparty/miniColors/GPL-LICENSE.txt b/3rdparty/miniColors/GPL-LICENSE.txt
new file mode 100644
index 00000000000..11dddd00ef0
--- /dev/null
+++ b/3rdparty/miniColors/GPL-LICENSE.txt
@@ -0,0 +1,278 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) 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
+this service 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 make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. 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.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute 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 and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+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
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the 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 a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, 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.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE 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.
diff --git a/3rdparty/miniColors/MIT-LICENSE.txt b/3rdparty/miniColors/MIT-LICENSE.txt
new file mode 100644
index 00000000000..ec6f7581576
--- /dev/null
+++ b/3rdparty/miniColors/MIT-LICENSE.txt
@@ -0,0 +1,20 @@
+Copyright (c) Cory LaViska
+
+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.
diff --git a/3rdparty/miniColors/css/images/colors.png b/3rdparty/miniColors/css/images/colors.png
new file mode 100755
index 00000000000..1b4f819d8d9
--- /dev/null
+++ b/3rdparty/miniColors/css/images/colors.png
Binary files differ
diff --git a/3rdparty/miniColors/css/images/trigger.png b/3rdparty/miniColors/css/images/trigger.png
new file mode 100755
index 00000000000..8c169fd6053
--- /dev/null
+++ b/3rdparty/miniColors/css/images/trigger.png
Binary files differ
diff --git a/3rdparty/miniColors/css/jquery.miniColors.css b/3rdparty/miniColors/css/jquery.miniColors.css
new file mode 100755
index 00000000000..381bc1dc065
--- /dev/null
+++ b/3rdparty/miniColors/css/jquery.miniColors.css
@@ -0,0 +1,81 @@
+.miniColors-trigger {
+ height: 22px;
+ width: 22px;
+ background: url(images/trigger.png) center no-repeat;
+ vertical-align: middle;
+ margin: 0 .25em;
+ display: inline-block;
+ outline: none;
+}
+
+.miniColors-selector {
+ position: absolute;
+ width: 175px;
+ height: 150px;
+ background: #FFF;
+ border: solid 1px #BBB;
+ -moz-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ -webkit-box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ box-shadow: 0 0 6px rgba(0, 0, 0, .25);
+ -moz-border-radius: 5px;
+ -webkit-border-radius: 5px;
+ border-radius: 5px;
+ padding: 5px;
+ z-index: 999999;
+}
+
+.miniColors-selector.black {
+ background: #000;
+ border-color: #000;
+}
+
+.miniColors-colors {
+ position: absolute;
+ top: 5px;
+ left: 5px;
+ width: 150px;
+ height: 150px;
+ background: url(images/colors.png) right no-repeat;
+ cursor: crosshair;
+}
+
+.miniColors-hues {
+ position: absolute;
+ top: 5px;
+ left: 160px;
+ width: 20px;
+ height: 150px;
+ background: url(images/colors.png) left no-repeat;
+ cursor: crosshair;
+}
+
+.miniColors-colorPicker {
+ position: absolute;
+ width: 9px;
+ height: 9px;
+ border: 1px solid #fff;
+ -moz-border-radius: 11px;
+ -webkit-border-radius: 11px;
+ border-radius: 11px;
+}
+.miniColors-colorPicker-inner {
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 7px;
+ height: 7px;
+ border: 1px solid #000;
+ -moz-border-radius: 9px;
+ -webkit-border-radius: 9px;
+ border-radius: 9px;
+}
+
+.miniColors-huePicker {
+ position: absolute;
+ left: -3px;
+ width: 24px;
+ height: 1px;
+ border: 1px solid #fff;
+ border-radius: 2px;
+ background: #000;
+} \ No newline at end of file
diff --git a/3rdparty/miniColors/js/jquery.miniColors.js b/3rdparty/miniColors/js/jquery.miniColors.js
new file mode 100755
index 00000000000..187db3fa84e
--- /dev/null
+++ b/3rdparty/miniColors/js/jquery.miniColors.js
@@ -0,0 +1,580 @@
+/*
+ * jQuery miniColors: A small color selector
+ *
+ * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
+ *
+ * Dual licensed under the MIT or GPL Version 2 licenses
+ *
+*/
+if(jQuery) (function($) {
+
+ $.extend($.fn, {
+
+ miniColors: function(o, data) {
+
+ var create = function(input, o, data) {
+ //
+ // Creates a new instance of the miniColors selector
+ //
+
+ // Determine initial color (defaults to white)
+ var color = expandHex(input.val());
+ if( !color ) color = 'ffffff';
+ var hsb = hex2hsb(color);
+
+ // Create trigger
+ var trigger = $('<a class="miniColors-trigger" style="background-color: #' + color + '" href="#"></a>');
+ trigger.insertAfter(input);
+
+ // Set input data and update attributes
+ input
+ .addClass('miniColors')
+ .data('original-maxlength', input.attr('maxlength') || null)
+ .data('original-autocomplete', input.attr('autocomplete') || null)
+ .data('letterCase', 'uppercase')
+ .data('trigger', trigger)
+ .data('hsb', hsb)
+ .data('change', o.change ? o.change : null)
+ .data('close', o.close ? o.close : null)
+ .data('open', o.open ? o.open : null)
+ .attr('maxlength', 7)
+ .attr('autocomplete', 'off')
+ .val('#' + convertCase(color, o.letterCase));
+
+ // Handle options
+ if( o.readonly ) input.prop('readonly', true);
+ if( o.disabled ) disable(input);
+
+ // Show selector when trigger is clicked
+ trigger.bind('click.miniColors', function(event) {
+ event.preventDefault();
+ if( input.val() === '' ) input.val('#');
+ show(input);
+
+ });
+
+ // Show selector when input receives focus
+ input.bind('focus.miniColors', function(event) {
+ if( input.val() === '' ) input.val('#');
+ show(input);
+ });
+
+ // Hide on blur
+ input.bind('blur.miniColors', function(event) {
+ var hex = expandHex( hsb2hex(input.data('hsb')) );
+ input.val( hex ? '#' + convertCase(hex, input.data('letterCase')) : '' );
+ });
+
+ // Hide when tabbing out of the input
+ input.bind('keydown.miniColors', function(event) {
+ if( event.keyCode === 9 ) hide(input);
+ });
+
+ // Update when color is typed in
+ input.bind('keyup.miniColors', function(event) {
+ setColorFromInput(input);
+ });
+
+ // Handle pasting
+ input.bind('paste.miniColors', function(event) {
+ // Short pause to wait for paste to complete
+ setTimeout( function() {
+ setColorFromInput(input);
+ }, 5);
+ });
+
+ };
+
+ var destroy = function(input) {
+ //
+ // Destroys an active instance of the miniColors selector
+ //
+
+ hide();
+ input = $(input);
+
+ // Restore to original state
+ input.data('trigger').remove();
+ input
+ .attr('autocomplete', input.data('original-autocomplete'))
+ .attr('maxlength', input.data('original-maxlength'))
+ .removeData()
+ .removeClass('miniColors')
+ .unbind('.miniColors');
+ $(document).unbind('.miniColors');
+ };
+
+ var enable = function(input) {
+ //
+ // Enables the input control and the selector
+ //
+ input
+ .prop('disabled', false)
+ .data('trigger')
+ .css('opacity', 1);
+ };
+
+ var disable = function(input) {
+ //
+ // Disables the input control and the selector
+ //
+ hide(input);
+ input
+ .prop('disabled', true)
+ .data('trigger')
+ .css('opacity', 0.5);
+ };
+
+ var show = function(input) {
+ //
+ // Shows the miniColors selector
+ //
+ if( input.prop('disabled') ) return false;
+
+ // Hide all other instances
+ hide();
+
+ // Generate the selector
+ var selector = $('<div class="miniColors-selector"></div>');
+ selector
+ .append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>')
+ .append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>')
+ .css({
+ top: input.is(':visible') ? input.offset().top + input.outerHeight() : input.data('trigger').offset().top + input.data('trigger').outerHeight(),
+ left: input.is(':visible') ? input.offset().left : input.data('trigger').offset().left,
+ display: 'none'
+ })
+ .addClass( input.attr('class') );
+
+ // Set background for colors
+ var hsb = input.data('hsb');
+ selector
+ .find('.miniColors-colors')
+ .css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
+
+ // Set colorPicker position
+ var colorPosition = input.data('colorPosition');
+ if( !colorPosition ) colorPosition = getColorPositionFromHSB(hsb);
+ selector.find('.miniColors-colorPicker')
+ .css('top', colorPosition.y + 'px')
+ .css('left', colorPosition.x + 'px');
+
+ // Set huePicker position
+ var huePosition = input.data('huePosition');
+ if( !huePosition ) huePosition = getHuePositionFromHSB(hsb);
+ selector.find('.miniColors-huePicker').css('top', huePosition.y + 'px');
+
+ // Set input data
+ input
+ .data('selector', selector)
+ .data('huePicker', selector.find('.miniColors-huePicker'))
+ .data('colorPicker', selector.find('.miniColors-colorPicker'))
+ .data('mousebutton', 0);
+
+ $('BODY').append(selector);
+ selector.fadeIn(100);
+
+ // Prevent text selection in IE
+ selector.bind('selectstart', function() { return false; });
+
+ $(document).bind('mousedown.miniColors touchstart.miniColors', function(event) {
+
+ input.data('mousebutton', 1);
+ var testSubject = $(event.target).parents().andSelf();
+
+ if( testSubject.hasClass('miniColors-colors') ) {
+ event.preventDefault();
+ input.data('moving', 'colors');
+ moveColor(input, event);
+ }
+
+ if( testSubject.hasClass('miniColors-hues') ) {
+ event.preventDefault();
+ input.data('moving', 'hues');
+ moveHue(input, event);
+ }
+
+ if( testSubject.hasClass('miniColors-selector') ) {
+ event.preventDefault();
+ return;
+ }
+
+ if( testSubject.hasClass('miniColors') ) return;
+
+ hide(input);
+ });
+
+ $(document)
+ .bind('mouseup.miniColors touchend.miniColors', function(event) {
+ event.preventDefault();
+ input.data('mousebutton', 0).removeData('moving');
+ })
+ .bind('mousemove.miniColors touchmove.miniColors', function(event) {
+ event.preventDefault();
+ if( input.data('mousebutton') === 1 ) {
+ if( input.data('moving') === 'colors' ) moveColor(input, event);
+ if( input.data('moving') === 'hues' ) moveHue(input, event);
+ }
+ });
+
+ // Fire open callback
+ if( input.data('open') ) {
+ input.data('open').call(input.get(0), '#' + hsb2hex(hsb), hsb2rgb(hsb));
+ }
+
+ };
+
+ var hide = function(input) {
+
+ //
+ // Hides one or more miniColors selectors
+ //
+
+ // Hide all other instances if input isn't specified
+ if( !input ) input = '.miniColors';
+
+ $(input).each( function() {
+ var selector = $(this).data('selector');
+ $(this).removeData('selector');
+ $(selector).fadeOut(100, function() {
+ // Fire close callback
+ if( input.data('close') ) {
+ var hsb = input.data('hsb'), hex = hsb2hex(hsb);
+ input.data('close').call(input.get(0), '#' + hex, hsb2rgb(hsb));
+ }
+ $(this).remove();
+ });
+ });
+
+ $(document).unbind('.miniColors');
+
+ };
+
+ var moveColor = function(input, event) {
+
+ var colorPicker = input.data('colorPicker');
+
+ colorPicker.hide();
+
+ var position = {
+ x: event.pageX,
+ y: event.pageY
+ };
+
+ // Touch support
+ if( event.originalEvent.changedTouches ) {
+ position.x = event.originalEvent.changedTouches[0].pageX;
+ position.y = event.originalEvent.changedTouches[0].pageY;
+ }
+ position.x = position.x - input.data('selector').find('.miniColors-colors').offset().left - 5;
+ position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 5;
+ if( position.x <= -5 ) position.x = -5;
+ if( position.x >= 144 ) position.x = 144;
+ if( position.y <= -5 ) position.y = -5;
+ if( position.y >= 144 ) position.y = 144;
+
+ input.data('colorPosition', position);
+ colorPicker.css('left', position.x).css('top', position.y).show();
+
+ // Calculate saturation
+ var s = Math.round((position.x + 5) * 0.67);
+ if( s < 0 ) s = 0;
+ if( s > 100 ) s = 100;
+
+ // Calculate brightness
+ var b = 100 - Math.round((position.y + 5) * 0.67);
+ if( b < 0 ) b = 0;
+ if( b > 100 ) b = 100;
+
+ // Update HSB values
+ var hsb = input.data('hsb');
+ hsb.s = s;
+ hsb.b = b;
+
+ // Set color
+ setColor(input, hsb, true);
+ };
+
+ var moveHue = function(input, event) {
+
+ var huePicker = input.data('huePicker');
+
+ huePicker.hide();
+
+ var position = {
+ y: event.pageY
+ };
+
+ // Touch support
+ if( event.originalEvent.changedTouches ) {
+ position.y = event.originalEvent.changedTouches[0].pageY;
+ }
+
+ position.y = position.y - input.data('selector').find('.miniColors-colors').offset().top - 1;
+ if( position.y <= -1 ) position.y = -1;
+ if( position.y >= 149 ) position.y = 149;
+ input.data('huePosition', position);
+ huePicker.css('top', position.y).show();
+
+ // Calculate hue
+ var h = Math.round((150 - position.y - 1) * 2.4);
+ if( h < 0 ) h = 0;
+ if( h > 360 ) h = 360;
+
+ // Update HSB values
+ var hsb = input.data('hsb');
+ hsb.h = h;
+
+ // Set color
+ setColor(input, hsb, true);
+
+ };
+
+ var setColor = function(input, hsb, updateInput) {
+ input.data('hsb', hsb);
+ var hex = hsb2hex(hsb);
+ if( updateInput ) input.val( '#' + convertCase(hex, input.data('letterCase')) );
+ input.data('trigger').css('backgroundColor', '#' + hex);
+ if( input.data('selector') ) input.data('selector').find('.miniColors-colors').css('backgroundColor', '#' + hsb2hex({ h: hsb.h, s: 100, b: 100 }));
+
+ // Fire change callback
+ if( input.data('change') ) {
+ if( hex === input.data('lastChange') ) return;
+ input.data('change').call(input.get(0), '#' + hex, hsb2rgb(hsb));
+ input.data('lastChange', hex);
+ }
+
+ };
+
+ var setColorFromInput = function(input) {
+
+ input.val('#' + cleanHex(input.val()));
+ var hex = expandHex(input.val());
+ if( !hex ) return false;
+
+ // Get HSB equivalent
+ var hsb = hex2hsb(hex);
+
+ // If color is the same, no change required
+ var currentHSB = input.data('hsb');
+ if( hsb.h === currentHSB.h && hsb.s === currentHSB.s && hsb.b === currentHSB.b ) return true;
+
+ // Set colorPicker position
+ var colorPosition = getColorPositionFromHSB(hsb);
+ var colorPicker = $(input.data('colorPicker'));
+ colorPicker.css('top', colorPosition.y + 'px').css('left', colorPosition.x + 'px');
+ input.data('colorPosition', colorPosition);
+
+ // Set huePosition position
+ var huePosition = getHuePositionFromHSB(hsb);
+ var huePicker = $(input.data('huePicker'));
+ huePicker.css('top', huePosition.y + 'px');
+ input.data('huePosition', huePosition);
+
+ setColor(input, hsb);
+
+ return true;
+
+ };
+
+ var convertCase = function(string, letterCase) {
+ if( letterCase === 'lowercase' ) return string.toLowerCase();
+ if( letterCase === 'uppercase' ) return string.toUpperCase();
+ return string;
+ };
+
+ var getColorPositionFromHSB = function(hsb) {
+ var x = Math.ceil(hsb.s / 0.67);
+ if( x < 0 ) x = 0;
+ if( x > 150 ) x = 150;
+ var y = 150 - Math.ceil(hsb.b / 0.67);
+ if( y < 0 ) y = 0;
+ if( y > 150 ) y = 150;
+ return { x: x - 5, y: y - 5 };
+ };
+
+ var getHuePositionFromHSB = function(hsb) {
+ var y = 150 - (hsb.h / 2.4);
+ if( y < 0 ) h = 0;
+ if( y > 150 ) h = 150;
+ return { y: y - 1 };
+ };
+
+ var cleanHex = function(hex) {
+ return hex.replace(/[^A-F0-9]/ig, '');
+ };
+
+ var expandHex = function(hex) {
+ hex = cleanHex(hex);
+ if( !hex ) return null;
+ if( hex.length === 3 ) hex = hex[0] + hex[0] + hex[1] + hex[1] + hex[2] + hex[2];
+ return hex.length === 6 ? hex : null;
+ };
+
+ var hsb2rgb = function(hsb) {
+ var rgb = {};
+ var h = Math.round(hsb.h);
+ var s = Math.round(hsb.s*255/100);
+ var v = Math.round(hsb.b*255/100);
+ if(s === 0) {
+ rgb.r = rgb.g = rgb.b = v;
+ } else {
+ var t1 = v;
+ var t2 = (255 - s) * v / 255;
+ var t3 = (t1 - t2) * (h % 60) / 60;
+ if( h === 360 ) h = 0;
+ if( h < 60 ) { rgb.r = t1; rgb.b = t2; rgb.g = t2 + t3; }
+ else if( h < 120 ) {rgb.g = t1; rgb.b = t2; rgb.r = t1 - t3; }
+ else if( h < 180 ) {rgb.g = t1; rgb.r = t2; rgb.b = t2 + t3; }
+ else if( h < 240 ) {rgb.b = t1; rgb.r = t2; rgb.g = t1 - t3; }
+ else if( h < 300 ) {rgb.b = t1; rgb.g = t2; rgb.r = t2 + t3; }
+ else if( h < 360 ) {rgb.r = t1; rgb.g = t2; rgb.b = t1 - t3; }
+ else { rgb.r = 0; rgb.g = 0; rgb.b = 0; }
+ }
+ return {
+ r: Math.round(rgb.r),
+ g: Math.round(rgb.g),
+ b: Math.round(rgb.b)
+ };
+ };
+
+ var rgb2hex = function(rgb) {
+ var hex = [
+ rgb.r.toString(16),
+ rgb.g.toString(16),
+ rgb.b.toString(16)
+ ];
+ $.each(hex, function(nr, val) {
+ if (val.length === 1) hex[nr] = '0' + val;
+ });
+ return hex.join('');
+ };
+
+ var hex2rgb = function(hex) {
+ hex = parseInt(((hex.indexOf('#') > -1) ? hex.substring(1) : hex), 16);
+
+ return {
+ r: hex >> 16,
+ g: (hex & 0x00FF00) >> 8,
+ b: (hex & 0x0000FF)
+ };
+ };
+
+ var rgb2hsb = function(rgb) {
+ var hsb = { h: 0, s: 0, b: 0 };
+ var min = Math.min(rgb.r, rgb.g, rgb.b);
+ var max = Math.max(rgb.r, rgb.g, rgb.b);
+ var delta = max - min;
+ hsb.b = max;
+ hsb.s = max !== 0 ? 255 * delta / max : 0;
+ if( hsb.s !== 0 ) {
+ if( rgb.r === max ) {
+ hsb.h = (rgb.g - rgb.b) / delta;
+ } else if( rgb.g === max ) {
+ hsb.h = 2 + (rgb.b - rgb.r) / delta;
+ } else {
+ hsb.h = 4 + (rgb.r - rgb.g) / delta;
+ }
+ } else {
+ hsb.h = -1;
+ }
+ hsb.h *= 60;
+ if( hsb.h < 0 ) {
+ hsb.h += 360;
+ }
+ hsb.s *= 100/255;
+ hsb.b *= 100/255;
+ return hsb;
+ };
+
+ var hex2hsb = function(hex) {
+ var hsb = rgb2hsb(hex2rgb(hex));
+ // Zero out hue marker for black, white, and grays (saturation === 0)
+ if( hsb.s === 0 ) hsb.h = 360;
+ return hsb;
+ };
+
+ var hsb2hex = function(hsb) {
+ return rgb2hex(hsb2rgb(hsb));
+ };
+
+
+ // Handle calls to $([selector]).miniColors()
+ switch(o) {
+
+ case 'readonly':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ $(this).prop('readonly', data);
+ });
+
+ return $(this);
+
+ case 'disabled':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ if( data ) {
+ disable($(this));
+ } else {
+ enable($(this));
+ }
+ });
+
+ return $(this);
+
+ case 'value':
+
+ // Getter
+ if( data === undefined ) {
+ if( !$(this).hasClass('miniColors') ) return;
+ var input = $(this),
+ hex = expandHex(input.val());
+ return hex ? '#' + convertCase(hex, input.data('letterCase')) : null;
+ }
+
+ // Setter
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ $(this).val(data);
+ setColorFromInput($(this));
+ });
+
+ return $(this);
+
+ case 'destroy':
+
+ $(this).each( function() {
+ if( !$(this).hasClass('miniColors') ) return;
+ destroy($(this));
+ });
+
+ return $(this);
+
+ default:
+
+ if( !o ) o = {};
+
+ $(this).each( function() {
+
+ // Must be called on an input element
+ if( $(this)[0].tagName.toLowerCase() !== 'input' ) return;
+
+ // If a trigger is present, the control was already created
+ if( $(this).data('trigger') ) return;
+
+ // Create the control
+ create($(this), o, data);
+
+ });
+
+ return $(this);
+
+ }
+
+ }
+
+ });
+
+})(jQuery); \ No newline at end of file
diff --git a/3rdparty/miniColors/js/jquery.miniColors.min.js b/3rdparty/miniColors/js/jquery.miniColors.min.js
new file mode 100755
index 00000000000..c00e0ace6b5
--- /dev/null
+++ b/3rdparty/miniColors/js/jquery.miniColors.min.js
@@ -0,0 +1,9 @@
+/*
+ * jQuery miniColors: A small color selector
+ *
+ * Copyright 2011 Cory LaViska for A Beautiful Site, LLC. (http://abeautifulsite.net/)
+ *
+ * Dual licensed under the MIT or GPL Version 2 licenses
+ *
+*/
+if(jQuery)(function($){$.extend($.fn,{miniColors:function(o,data){var create=function(input,o,data){var color=expandHex(input.val());if(!color)color='ffffff';var hsb=hex2hsb(color);var trigger=$('<a class="miniColors-trigger" style="background-color: #'+color+'" href="#"></a>');trigger.insertAfter(input);input.addClass('miniColors').data('original-maxlength',input.attr('maxlength')||null).data('original-autocomplete',input.attr('autocomplete')||null).data('letterCase','uppercase').data('trigger',trigger).data('hsb',hsb).data('change',o.change?o.change:null).data('close',o.close?o.close:null).data('open',o.open?o.open:null).attr('maxlength',7).attr('autocomplete','off').val('#'+convertCase(color,o.letterCase));if(o.readonly)input.prop('readonly',true);if(o.disabled)disable(input);trigger.bind('click.miniColors',function(event){event.preventDefault();if(input.val()==='')input.val('#');show(input)});input.bind('focus.miniColors',function(event){if(input.val()==='')input.val('#');show(input)});input.bind('blur.miniColors',function(event){var hex=expandHex(hsb2hex(input.data('hsb')));input.val(hex?'#'+convertCase(hex,input.data('letterCase')):'')});input.bind('keydown.miniColors',function(event){if(event.keyCode===9)hide(input)});input.bind('keyup.miniColors',function(event){setColorFromInput(input)});input.bind('paste.miniColors',function(event){setTimeout(function(){setColorFromInput(input)},5)})};var destroy=function(input){hide();input=$(input);input.data('trigger').remove();input.attr('autocomplete',input.data('original-autocomplete')).attr('maxlength',input.data('original-maxlength')).removeData().removeClass('miniColors').unbind('.miniColors');$(document).unbind('.miniColors')};var enable=function(input){input.prop('disabled',false).data('trigger').css('opacity',1)};var disable=function(input){hide(input);input.prop('disabled',true).data('trigger').css('opacity',0.5)};var show=function(input){if(input.prop('disabled'))return false;hide();var selector=$('<div class="miniColors-selector"></div>');selector.append('<div class="miniColors-colors" style="background-color: #FFF;"><div class="miniColors-colorPicker"><div class="miniColors-colorPicker-inner"></div></div>').append('<div class="miniColors-hues"><div class="miniColors-huePicker"></div></div>').css({top:input.is(':visible')?input.offset().top+input.outerHeight():input.data('trigger').offset().top+input.data('trigger').outerHeight(),left:input.is(':visible')?input.offset().left:input.data('trigger').offset().left,display:'none'}).addClass(input.attr('class'));var hsb=input.data('hsb');selector.find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));var colorPosition=input.data('colorPosition');if(!colorPosition)colorPosition=getColorPositionFromHSB(hsb);selector.find('.miniColors-colorPicker').css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');var huePosition=input.data('huePosition');if(!huePosition)huePosition=getHuePositionFromHSB(hsb);selector.find('.miniColors-huePicker').css('top',huePosition.y+'px');input.data('selector',selector).data('huePicker',selector.find('.miniColors-huePicker')).data('colorPicker',selector.find('.miniColors-colorPicker')).data('mousebutton',0);$('BODY').append(selector);selector.fadeIn(100);selector.bind('selectstart',function(){return false});$(document).bind('mousedown.miniColors touchstart.miniColors',function(event){input.data('mousebutton',1);var testSubject=$(event.target).parents().andSelf();if(testSubject.hasClass('miniColors-colors')){event.preventDefault();input.data('moving','colors');moveColor(input,event)}if(testSubject.hasClass('miniColors-hues')){event.preventDefault();input.data('moving','hues');moveHue(input,event)}if(testSubject.hasClass('miniColors-selector')){event.preventDefault();return}if(testSubject.hasClass('miniColors'))return;hide(input)});$(document).bind('mouseup.miniColors touchend.miniColors',function(event){event.preventDefault();input.data('mousebutton',0).removeData('moving')}).bind('mousemove.miniColors touchmove.miniColors',function(event){event.preventDefault();if(input.data('mousebutton')===1){if(input.data('moving')==='colors')moveColor(input,event);if(input.data('moving')==='hues')moveHue(input,event)}});if(input.data('open')){input.data('open').call(input.get(0),'#'+hsb2hex(hsb),hsb2rgb(hsb))}};var hide=function(input){if(!input)input='.miniColors';$(input).each(function(){var selector=$(this).data('selector');$(this).removeData('selector');$(selector).fadeOut(100,function(){if(input.data('close')){var hsb=input.data('hsb'),hex=hsb2hex(hsb);input.data('close').call(input.get(0),'#'+hex,hsb2rgb(hsb))}$(this).remove()})});$(document).unbind('.miniColors')};var moveColor=function(input,event){var colorPicker=input.data('colorPicker');colorPicker.hide();var position={x:event.pageX,y:event.pageY};if(event.originalEvent.changedTouches){position.x=event.originalEvent.changedTouches[0].pageX;position.y=event.originalEvent.changedTouches[0].pageY}position.x=position.x-input.data('selector').find('.miniColors-colors').offset().left-5;position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-5;if(position.x<=-5)position.x=-5;if(position.x>=144)position.x=144;if(position.y<=-5)position.y=-5;if(position.y>=144)position.y=144;input.data('colorPosition',position);colorPicker.css('left',position.x).css('top',position.y).show();var s=Math.round((position.x+5)*0.67);if(s<0)s=0;if(s>100)s=100;var b=100-Math.round((position.y+5)*0.67);if(b<0)b=0;if(b>100)b=100;var hsb=input.data('hsb');hsb.s=s;hsb.b=b;setColor(input,hsb,true)};var moveHue=function(input,event){var huePicker=input.data('huePicker');huePicker.hide();var position={y:event.pageY};if(event.originalEvent.changedTouches){position.y=event.originalEvent.changedTouches[0].pageY}position.y=position.y-input.data('selector').find('.miniColors-colors').offset().top-1;if(position.y<=-1)position.y=-1;if(position.y>=149)position.y=149;input.data('huePosition',position);huePicker.css('top',position.y).show();var h=Math.round((150-position.y-1)*2.4);if(h<0)h=0;if(h>360)h=360;var hsb=input.data('hsb');hsb.h=h;setColor(input,hsb,true)};var setColor=function(input,hsb,updateInput){input.data('hsb',hsb);var hex=hsb2hex(hsb);if(updateInput)input.val('#'+convertCase(hex,input.data('letterCase')));input.data('trigger').css('backgroundColor','#'+hex);if(input.data('selector'))input.data('selector').find('.miniColors-colors').css('backgroundColor','#'+hsb2hex({h:hsb.h,s:100,b:100}));if(input.data('change')){if(hex===input.data('lastChange'))return;input.data('change').call(input.get(0),'#'+hex,hsb2rgb(hsb));input.data('lastChange',hex)}};var setColorFromInput=function(input){input.val('#'+cleanHex(input.val()));var hex=expandHex(input.val());if(!hex)return false;var hsb=hex2hsb(hex);var currentHSB=input.data('hsb');if(hsb.h===currentHSB.h&&hsb.s===currentHSB.s&&hsb.b===currentHSB.b)return true;var colorPosition=getColorPositionFromHSB(hsb);var colorPicker=$(input.data('colorPicker'));colorPicker.css('top',colorPosition.y+'px').css('left',colorPosition.x+'px');input.data('colorPosition',colorPosition);var huePosition=getHuePositionFromHSB(hsb);var huePicker=$(input.data('huePicker'));huePicker.css('top',huePosition.y+'px');input.data('huePosition',huePosition);setColor(input,hsb);return true};var convertCase=function(string,letterCase){if(letterCase==='lowercase')return string.toLowerCase();if(letterCase==='uppercase')return string.toUpperCase();return string};var getColorPositionFromHSB=function(hsb){var x=Math.ceil(hsb.s/0.67);if(x<0)x=0;if(x>150)x=150;var y=150-Math.ceil(hsb.b/0.67);if(y<0)y=0;if(y>150)y=150;return{x:x-5,y:y-5}};var getHuePositionFromHSB=function(hsb){var y=150-(hsb.h/2.4);if(y<0)h=0;if(y>150)h=150;return{y:y-1}};var cleanHex=function(hex){return hex.replace(/[^A-F0-9]/ig,'')};var expandHex=function(hex){hex=cleanHex(hex);if(!hex)return null;if(hex.length===3)hex=hex[0]+hex[0]+hex[1]+hex[1]+hex[2]+hex[2];return hex.length===6?hex:null};var hsb2rgb=function(hsb){var rgb={};var h=Math.round(hsb.h);var s=Math.round(hsb.s*255/100);var v=Math.round(hsb.b*255/100);if(s===0){rgb.r=rgb.g=rgb.b=v}else{var t1=v;var t2=(255-s)*v/255;var t3=(t1-t2)*(h%60)/60;if(h===360)h=0;if(h<60){rgb.r=t1;rgb.b=t2;rgb.g=t2+t3}else if(h<120){rgb.g=t1;rgb.b=t2;rgb.r=t1-t3}else if(h<180){rgb.g=t1;rgb.r=t2;rgb.b=t2+t3}else if(h<240){rgb.b=t1;rgb.r=t2;rgb.g=t1-t3}else if(h<300){rgb.b=t1;rgb.g=t2;rgb.r=t2+t3}else if(h<360){rgb.r=t1;rgb.g=t2;rgb.b=t1-t3}else{rgb.r=0;rgb.g=0;rgb.b=0}}return{r:Math.round(rgb.r),g:Math.round(rgb.g),b:Math.round(rgb.b)}};var rgb2hex=function(rgb){var hex=[rgb.r.toString(16),rgb.g.toString(16),rgb.b.toString(16)];$.each(hex,function(nr,val){if(val.length===1)hex[nr]='0'+val});return hex.join('')};var hex2rgb=function(hex){hex=parseInt(((hex.indexOf('#')>-1)?hex.substring(1):hex),16);return{r:hex>>16,g:(hex&0x00FF00)>>8,b:(hex&0x0000FF)}};var rgb2hsb=function(rgb){var hsb={h:0,s:0,b:0};var min=Math.min(rgb.r,rgb.g,rgb.b);var max=Math.max(rgb.r,rgb.g,rgb.b);var delta=max-min;hsb.b=max;hsb.s=max!==0?255*delta/max:0;if(hsb.s!==0){if(rgb.r===max){hsb.h=(rgb.g-rgb.b)/delta}else if(rgb.g===max){hsb.h=2+(rgb.b-rgb.r)/delta}else{hsb.h=4+(rgb.r-rgb.g)/delta}}else{hsb.h=-1}hsb.h*=60;if(hsb.h<0){hsb.h+=360}hsb.s*=100/255;hsb.b*=100/255;return hsb};var hex2hsb=function(hex){var hsb=rgb2hsb(hex2rgb(hex));if(hsb.s===0)hsb.h=360;return hsb};var hsb2hex=function(hsb){return rgb2hex(hsb2rgb(hsb))};switch(o){case'readonly':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).prop('readonly',data)});return $(this);case'disabled':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;if(data){disable($(this))}else{enable($(this))}});return $(this);case'value':if(data===undefined){if(!$(this).hasClass('miniColors'))return;var input=$(this),hex=expandHex(input.val());return hex?'#'+convertCase(hex,input.data('letterCase')):null}$(this).each(function(){if(!$(this).hasClass('miniColors'))return;$(this).val(data);setColorFromInput($(this))});return $(this);case'destroy':$(this).each(function(){if(!$(this).hasClass('miniColors'))return;destroy($(this))});return $(this);default:if(!o)o={};$(this).each(function(){if($(this)[0].tagName.toLowerCase()!=='input')return;if($(this).data('trigger'))return;create($(this),o,data)});return $(this)}}})})(jQuery); \ No newline at end of file
diff --git a/apps/user_openid/class.openid.v3.php b/3rdparty/openid/class.openid.v3.php
index eeb31986659..eeb31986659 100644
--- a/apps/user_openid/class.openid.v3.php
+++ b/3rdparty/openid/class.openid.v3.php
diff --git a/apps/user_openid/phpmyid.php b/3rdparty/openid/phpmyid.php
index 13fd31c47ca..13fd31c47ca 100644
--- a/apps/user_openid/phpmyid.php
+++ b/3rdparty/openid/phpmyid.php
diff --git a/apps/calendar/ajax/import/calendarcheck.php b/apps/calendar/ajax/import/calendarcheck.php
new file mode 100644
index 00000000000..a91bab70573
--- /dev/null
+++ b/apps/calendar/ajax/import/calendarcheck.php
@@ -0,0 +1,18 @@
+<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+OCP\JSON::checkLoggedIn();
+OCP\App::checkAppEnabled('calendar');
+$calname = strip_tags($_POST['calname']);
+$calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
+foreach($calendars as $calendar){
+ if($calendar['displayname'] == $calname){
+ OCP\JSON::success(array('message'=>'exists'));
+ exit;
+ }
+}
+OCP\JSON::error(); \ No newline at end of file
diff --git a/apps/calendar/ajax/import/dialog.php b/apps/calendar/ajax/import/dialog.php
index b99c32278c4..18fe226172c 100644
--- a/apps/calendar/ajax/import/dialog.php
+++ b/apps/calendar/ajax/import/dialog.php
@@ -5,8 +5,6 @@
* later.
* See the COPYING-README file.
*/
-
-
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
$tmpl = new OCP\Template('calendar', 'part.import');
diff --git a/apps/calendar/ajax/import/dropimport.php b/apps/calendar/ajax/import/dropimport.php
index 87667d4de68..f46e7314098 100644
--- a/apps/calendar/ajax/import/dropimport.php
+++ b/apps/calendar/ajax/import/dropimport.php
@@ -1,73 +1,32 @@
<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
$data = $_POST['data'];
$data = explode(',', $data);
$data = end($data);
$data = base64_decode($data);
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
-$nl="\r\n";
-$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
-$data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
-$lines = explode("\n", $data);
-unset($data);
-$comp=$uid=$cal=false;
-$cals=$uids=array();
-$i = 0;
-foreach($lines as $line) {
- if(strpos($line, ':')!==false) {
- list($attr, $val) = explode(':', strtoupper($line));
- if ($attr == 'BEGIN' && $val == 'VCALENDAR') {
- $cal = $i;
- $cals[$cal] = array('first'=>$i,'last'=>$i,'end'=>$i);
- } elseif ($attr =='BEGIN' && $cal!==false && isset($comps[$val])) {
- $comp = $val;
- $beginNo = $i;
- } elseif ($attr == 'END' && $cal!==false && $val == 'VCALENDAR') {
- if($comp!==false) {
- unset($cals[$cal]); // corrupt calendar, unset it
- } else {
- $cals[$cal]['end'] = $i;
- }
- $comp=$uid=$cal=false; // reset calendar
- } elseif ($attr == 'END' && $comp!==false && $val == $comp) {
- if(! $uid) {
- $uid = OC_Calendar_Object::createUID();
- }
- $uids[$uid][$beginNo] = array('end'=>$i, 'cal'=>$cal);
- if ($cals[$cal]['first'] == $cal) {
- $cals[$cal]['first'] = $beginNo;
- }
- $cals[$cal]['last'] = $i;
- $comp=$uid=false; // reset component
- } elseif ($attr =="UID" && $comp!==false) {
- list($attr, $uid) = explode(':', $line);
- }
- }
- $i++;
+$import = new OC_Calendar_Import($data);
+$import->setUserID(OCP\User::getUser());
+$import->setTimeZone(OC_Calendar_App::$tz);
+$import->disableProgressCache();
+if(!$import->isValid()){
+ OCP\JSON::error();
+ exit;
}
-$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), true);
-$id = $calendars[0]['id'];
-foreach($uids as $uid) {
- $prefix=$suffix=$content=array();
- foreach($uid as $begin=>$details) {
- $cal = $details['cal'];
- if(!isset($cals[$cal])) {
- continue; // from corrupt/incomplete calendar
- }
- $cdata = $cals[$cal];
- // if we have multiple components from different calendar objects,
- // we should really merge their elements (enhancement?) -- 1st one wins for now.
- if(! count($prefix)) {
- $prefix = array_slice($lines, $cal, $cdata['first'] - $cal);
- }
- if(! count($suffix)) {
- $suffix = array_slice($lines, $cdata['last']+1, $cdata['end'] - $cdata['last']);
- }
- $content = array_merge($content, array_slice($lines, $begin, $details['end'] - $begin + 1));
- }
- if(count($content)) {
- $import = join($nl, array_merge($prefix, $content, $suffix)) . $nl;
- OC_Calendar_Object::add($id, $import);
- }
-}
-OCP\JSON::success(); \ No newline at end of file
+$newcalendarname = strip_tags($import->createCalendarName());
+$newid = OC_Calendar_Calendar::addCalendar(OCP\User::getUser(),$newcalendarname,'VEVENT,VTODO,VJOURNAL',null,0,$import->createCalendarColor());
+$import->setCalendarID($newid);
+$import->import();
+$count = $import->getCount();
+if($count == 0){
+ OC_Calendar_Calendar::deleteCalendar($newid);
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
+}else{
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . $newcalendarname, 'eventSource'=>OC_Calendar_Calendar::getEventSourceInfo(OC_Calendar_Calendar::find($newid))));
+} \ No newline at end of file
diff --git a/apps/calendar/ajax/import/import.php b/apps/calendar/ajax/import/import.php
index 38008af4a9d..b1dfc464d00 100644
--- a/apps/calendar/ajax/import/import.php
+++ b/apps/calendar/ajax/import/import.php
@@ -5,42 +5,71 @@
* later.
* See the COPYING-README file.
*/
-//check for calendar rights or create new one
-ob_start();
-
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
OCP\JSON::callCheck();
session_write_close();
-
-$nl="\r\n";
-$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
-
-global $progresskey;
-$progresskey = 'calendar.import-' . $_POST['progresskey'];
-
-if (isset($_POST['progress']) && $_POST['progress']) {
- echo OC_Cache::get($progresskey);
- die;
+if (isset($_POST['progresskey']) && isset($_POST['getprogress'])) {
+ echo OCP\JSON::success(array('percent'=>OC_Cache::get($_POST['progresskey'])));
+ exit;
}
-
-function writeProgress($pct) {
- global $progresskey;
- OC_Cache::set($progresskey, $pct, 300);
-}
-writeProgress('10');
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);
+if(!$file){
+ OCP\JSON::error(array('error'=>'404'));
+}
+$import = new OC_Calendar_Import($file);
+$import->setUserID(OCP\User::getUser());
+$import->setTimeZone(OC_Calendar_App::$tz);
+$import->enableProgressCache();
+$import->setProgresskey($_POST['progresskey']);
+if(!$import->isValid()){
+ OCP\JSON::error(array('error'=>'notvalid'));
+ exit;
+}
+$newcal = false;
if($_POST['method'] == 'new'){
- $id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), $_POST['calname']);
- OC_Calendar_Calendar::setCalendarActive($id, 1);
+ $calendars = OC_Calendar_Calendar::allCalendars(OCP\User::getUser());
+ foreach($calendars as $calendar){
+ if($calendar['displayname'] == $_POST['calname']){
+ $id = $calendar['id'];
+ $newcal = false;
+ break;
+ }
+ $newcal = true;
+ }
+ if($newcal){
+ $id = OC_Calendar_Calendar::addCalendar(OCP\USER::getUser(), strip_tags($_POST['calname']),'VEVENT,VTODO,VJOURNAL',null,0,strip_tags($_POST['calcolor']));
+ OC_Calendar_Calendar::setCalendarActive($id, 1);
+ }
}else{
$calendar = OC_Calendar_App::getCalendar($_POST['id']);
if($calendar['userid'] != OCP\USER::getUser()){
- OCP\JSON::error();
+ OCP\JSON::error(array('error'=>'missingcalendarrights'));
exit();
}
$id = $_POST['id'];
}
+$import->setCalendarID($id);
+try{
+ $import->import();
+}catch (Exception $e) {
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('Import failed'), 'debug'=>$e->getMessage()));
+ //write some log
+}
+$count = $import->getCount();
+if($count == 0){
+ if($newcal){
+ OC_Calendar_Calendar::deleteCalendar($id);
+ }
+ OCP\JSON::error(array('message'=>OC_Calendar_App::$l10n->t('The file contained either no events or all events are already saved in your calendar.')));
+}else{
+ if($newcal){
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in the new calendar') . ' ' . strip_tags($_POST['calname'])));
+ }else{
+ OCP\JSON::success(array('message'=>$count . ' ' . OC_Calendar_App::$l10n->t('events has been saved in your calendar')));
+ }
+}
+/* //////////////////////////// Attention: following code is quite painfull !!! ///////////////////////
writeProgress('20');
// normalize the newlines
$file = str_replace(array("\r","\n\n"), array("\n","\n"), $file);
@@ -92,7 +121,6 @@ foreach($lines as $line) {
// import the calendar
writeProgress('60');
foreach($uids as $uid) {
-
$prefix=$suffix=$content=array();
foreach($uid as $begin=>$details) {
@@ -120,4 +148,4 @@ foreach($uids as $uid) {
writeProgress('100');
sleep(3);
OC_Cache::remove($progresskey);
-OCP\JSON::success(); \ No newline at end of file
+OCP\JSON::success();*/
diff --git a/apps/calendar/appinfo/app.php b/apps/calendar/appinfo/app.php
index c8fccc326c3..4fdba291262 100644
--- a/apps/calendar/appinfo/app.php
+++ b/apps/calendar/appinfo/app.php
@@ -9,6 +9,7 @@ OC::$CLASSPATH['OC_Calendar_Repeat'] = 'apps/calendar/lib/repeat.php';
OC::$CLASSPATH['OC_Calendar_Share'] = 'apps/calendar/lib/share.php';
OC::$CLASSPATH['OC_Search_Provider_Calendar'] = 'apps/calendar/lib/search.php';
OC::$CLASSPATH['OC_Calendar_Export'] = 'apps/calendar/lib/export.php';
+OC::$CLASSPATH['OC_Calendar_Import'] = 'apps/calendar/lib/import.php';
//General Hooks
OCP\Util::connectHook('OC_User', 'post_createUser', 'OC_Calendar_Hooks', 'createUser');
OCP\Util::connectHook('OC_User', 'post_deleteUser', 'OC_Calendar_Hooks', 'deleteUser');
@@ -24,6 +25,8 @@ OCP\Util::connectHook('OC_Calendar', 'deleteCalendar', 'OC_Calendar_Share', 'pos
OCP\Util::addscript('calendar','loader');
OCP\Util::addscript("3rdparty", "chosen/chosen.jquery.min");
OCP\Util::addStyle("3rdparty", "chosen/chosen");
+OCP\Util::addStyle('3rdparty/miniColors', 'jquery.miniColors');
+OCP\Util::addscript('3rdparty/miniColors', 'jquery.miniColors.min');
OCP\App::addNavigationEntry( array(
'id' => 'calendar_index',
'order' => 10,
diff --git a/apps/calendar/css/import.css b/apps/calendar/css/import.css
new file mode 100644
index 00000000000..8abdc3aecd1
--- /dev/null
+++ b/apps/calendar/css/import.css
@@ -0,0 +1,14 @@
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev at georgswebsite dot de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+#calendar_import_newcalform, #calendar_import_mergewarning, #calendar_import_process, #calendar_import_done{display:none;}
+#calendar_import_process_message, #calendar_import_status, #calendar_import_form_message, #calendar_import_mergewarning{text-align:center;}
+#calendar_import_form_message{font-weight: bold;}
+#calendar_import_newcalendar{width:415px;float:right;}
+#calendar_import_mergewarning{clear: both;}
+#calendar_import_defaultcolors{clear:both;margin: 0 auto;text-align: center;}
+.calendar_import_warning{border-color: #fc3333;}
+.calendar-colorpicker-color{display:inline-block;width:20px;height:5px;margin: 0 auto;cursor:pointer;border:2px solid transparent;} \ No newline at end of file
diff --git a/apps/calendar/js/calendar.js b/apps/calendar/js/calendar.js
index 004b2386fb1..25311fa0df4 100644
--- a/apps/calendar/js/calendar.js
+++ b/apps/calendar/js/calendar.js
@@ -622,18 +622,11 @@ Calendar={
drop:function(e){
var files = e.dataTransfer.files;
for(var i = 0;i < files.length;i++){
- var file = files[i]
+ var file = files[i];
reader = new FileReader();
reader.onload = function(event){
- if(file.type != 'text/calendar'){
- $('#notification').html('At least one file don\'t seems to be a calendar file. File skipped.');
- $('#notification').slideDown();
- window.setTimeout(function(){$('#notification').slideUp();}, 5000);
- return false;
- }else{
- Calendar.UI.Drop.import(event.target.result);
- $('#calendar_holder').fullCalendar('refetchEvents');
- }
+ Calendar.UI.Drop.import(event.target.result);
+ $('#calendar_holder').fullCalendar('refetchEvents');
}
reader.readAsDataURL(file);
}
@@ -641,9 +634,13 @@ Calendar={
import:function(data){
$.post(OC.filePath('calendar', 'ajax/import', 'dropimport.php'), {'data':data},function(result) {
if(result.status == 'success'){
+ $('#calendar_holder').fullCalendar('addEventSource', result.eventSource);
+ $('#notification').html(result.message);
+ $('#notification').slideDown();
+ window.setTimeout(function(){$('#notification').slideUp();}, 5000);
return true;
}else{
- $('#notification').html('ownCloud wasn\'t able to import at least one file. File skipped.');
+ $('#notification').html(result.message);
$('#notification').slideDown();
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
}
diff --git a/apps/calendar/js/loader.js b/apps/calendar/js/loader.js
index cef95afc3aa..b28d19ab00e 100644
--- a/apps/calendar/js/loader.js
+++ b/apps/calendar/js/loader.js
@@ -5,77 +5,175 @@
* See the COPYING-README file.
*/
Calendar_Import={
- importdialog: function(filename){
- var path = $('#dir').val();
- $('body').append('<div id="calendar_import"></div>');
- $('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:filename, path:path}, function(){Calendar_Import.initdialog(filename);});
+ Store:{
+ file: '',
+ path: '',
+ id: 0,
+ method: '',
+ calname: '',
+ calcolor: '',
+ progresskey: '',
+ percentage: 0
},
- initdialog: function(filename){
- $('#calendar_import_dialog').dialog({
- width : 500,
- close : function() {
- $(this).dialog('destroy').remove();
- $('#calendar_import').remove();
+ Dialog:{
+ open: function(filename){
+ OC.addStyle('calendar', 'import');
+ Calendar_Import.Store.file = filename;
+ Calendar_Import.Store.path = $('#dir').val();
+ $('body').append('<div id="calendar_import"></div>');
+ $('#calendar_import').load(OC.filePath('calendar', 'ajax/import', 'dialog.php'), {filename:Calendar_Import.Store.file, path:Calendar_Import.Store.path},function(){
+ Calendar_Import.Dialog.init();
+ });
+ },
+ close: function(){
+ Calendar_Import.reset();
+ $(this).dialog('destroy').remove();
+ $('#calendar_import_dialog').remove();
+ },
+ init: function(){
+ //init dialog
+ $('#calendar_import_dialog').dialog({
+ width : 500,
+ resizable: false,
+ close : function() {
+ Calendar_Import.Dialog.close();
+ }
+ });
+ //init buttons
+ $('#calendar_import_done').click(function(){
+ Calendar_Import.Dialog.close();
+ });
+ $('#calendar_import_submit').click(function(){
+ Calendar_Import.Core.process();
+ });
+ $('#calendar_import_mergewarning').click(function(){
+ $('#calendar_import_newcalendar').attr('value', $('#calendar_import_availablename').val());
+ Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
+ });
+ $('#calendar_import_calendar').change(function(){
+ if($('#calendar_import_calendar option:selected').val() == 'newcal'){
+ $('#calendar_import_newcalform').slideDown('slow');
+ Calendar_Import.Dialog.mergewarning($('#calendar_import_newcalendar').val());
+ }else{
+ $('#calendar_import_newcalform').slideUp('slow');
+ $('#calendar_import_mergewarning').slideUp('slow');
+ }
+ });
+ $('#calendar_import_newcalendar').keyup(function(){
+ Calendar_Import.Dialog.mergewarning($.trim($('#calendar_import_newcalendar').val()));
+ });
+ $('#calendar_import_newcalendar_color').miniColors({
+ letterCase: 'uppercase'
+ });
+ $('.calendar-colorpicker-color').click(function(){
+ var str = $(this).attr('rel');
+ str = str.substr(1);
+ $('#calendar_import_newcalendar_color').attr('value', str);
+ $(".color-picker").miniColors('value', '#' + str);
+ });
+ //init progressbar
+ $('#calendar_import_progressbar').progressbar({value: Calendar_Import.Store.percentage});
+ Calendar_Import.Store.progresskey = $('#calendar_import_progresskey').val();
+ },
+ mergewarning: function(newcalname){
+ $.post(OC.filePath('calendar', 'ajax/import', 'calendarcheck.php'), {calname: newcalname}, function(data){
+ if(data.message == 'exists'){
+ $('#calendar_import_mergewarning').slideDown('slow');
+ }else{
+ $('#calendar_import_mergewarning').slideUp('slow');
+ }
+ });
+ },
+ update: function(){
+ if(Calendar_Import.Store.percentage == 100){
+ return false;
}
- });
- $('#import_done_button').click(function(){
- $('#calendar_import_dialog').dialog('destroy').remove();
- $('#calendar_import').remove();
- });
- $('#progressbar').progressbar({value: 0});
- $('#startimport').click(function(){
- var filename = $('#filename').val();
- var path = $('#path').val();
- var calid = $('#calendar option:selected').val();
- if($('#calendar option:selected').val() == 'newcal'){
- var method = 'new';
- var calname = $('#newcalendar').val();
- var calname = $.trim(calname);
- if(calname == ''){
- $('#newcalendar').css('background-color', '#FF2626');
- $('#newcalendar').focus(function(){
- $('#newcalendar').css('background-color', '#F8F8F8');
- });
- return false;
+ $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: Calendar_Import.Store.progresskey, getprogress: true}, function(data){
+ if(data.status == 'success'){
+ if(data.percent == null){
+ return false;
+ }
+ Calendar_Import.Store.percentage = parseInt(data.percent);
+ $('#calendar_import_progressbar').progressbar('option', 'value', parseInt(data.percent));
+ if(data.percent < 100 ){
+ window.setTimeout('Calendar_Import.Dialog.update()', 250);
+ }else{
+ $('#calendar_import_done').css('display', 'block');
+ }
+ }else{
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ $('#calendar_import_progressbar > div').css('background-color', '#FF2626');
+ $('#calendar_import_status').html(data.message);
}
- }else{
- var method = 'old';
+ });
+ return 0;
+ },
+ warning: function(selector){
+ $(selector).addClass('calendar_import_warning');
+ $(selector).focus(function(){
+ $(selector).removeClass('calendar_import_warning');
+ });
+ }
+ },
+ Core:{
+ process: function(){
+ var validation = Calendar_Import.Core.prepare();
+ if(validation){
+ $('#calendar_import_form').css('display', 'none');
+ $('#calendar_import_process').css('display', 'block');
+ $('#calendar_import_newcalendar').attr('readonly', 'readonly');
+ $('#calendar_import_calendar').attr('disabled', 'disabled');
+ Calendar_Import.Core.send();
+ window.setTimeout('Calendar_Import.Dialog.update()', 250);
}
- $('#newcalendar').attr('readonly', 'readonly');
- $('#calendar').attr('disabled', 'disabled');
- var progresskey = $('#progresskey').val();
- $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progresskey: progresskey, method: String (method), calname: String (calname), path: String (path), file: String (filename), id: String (calid)}, function(data){
+ },
+ send: function(){
+ $.post(OC.filePath('calendar', 'ajax/import', 'import.php'),
+ {progresskey: Calendar_Import.Store.progresskey, method: String (Calendar_Import.Store.method), calname: String (Calendar_Import.Store.calname), path: String (Calendar_Import.Store.path), file: String (Calendar_Import.Store.file), id: String (Calendar_Import.Store.id), calcolor: String (Calendar_Import.Store.calcolor)}, function(data){
if(data.status == 'success'){
- $('#progressbar').progressbar('option', 'value', 100);
- $('#import_done').css('display', 'block');
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ Calendar_Import.Store.percentage = 100;
+ $('#calendar_import_done').css('display', 'block');
+ $('#calendar_import_status').html(data.message);
+ }else{
+ $('#calendar_import_progressbar').progressbar('option', 'value', 100);
+ $('#calendar_import_progressbar > div').css('background-color', '#FF2626');
+ $('#calendar_import_status').html(data.message);
}
});
- $('#form_container').css('display', 'none');
- $('#progressbar_container').css('display', 'block');
- window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
- });
- $('#calendar').change(function(){
- if($('#calendar option:selected').val() == 'newcal'){
- $('#newcalform').slideDown('slow');
+ },
+ prepare: function(){
+ Calendar_Import.Store.id = $('#calendar_import_calendar option:selected').val();
+ if($('#calendar_import_calendar option:selected').val() == 'newcal'){
+ Calendar_Import.Store.method = 'new';
+ Calendar_Import.Store.calname = $.trim($('#calendar_import_newcalendar').val());
+ if(Calendar_Import.Store.calname == ''){
+ Calendar_Import.Dialog.warning('#calendar_import_newcalendar');
+ return false;
+ }
+ Calendar_Import.Store.calcolor = $.trim($('#calendar_import_newcalendar_color').val());
+ if(Calendar_Import.Store.calcolor == ''){
+ Calendar_Import.Store.calcolor = $('.calendar-colorpicker-color:first').attr('rel');
+ }
}else{
- $('#newcalform').slideUp('slow');
+ Calendar_Import.Store.method = 'old';
}
- });
+ return true;
+ }
},
- getimportstatus: function(progresskey){
- $.post(OC.filePath('calendar', 'ajax/import', 'import.php'), {progress:1,progresskey: progresskey}, function(percent){
- $('#progressbar').progressbar('option', 'value', parseInt(percent));
- if(percent < 100){
- window.setTimeout('Calendar_Import.getimportstatus(\'' + progresskey + '\')', 500);
- }else{
- $('#import_done').css('display', 'block');
- }
- });
+ reset: function(){
+ Calendar_Import.Store.file = '';
+ Calendar_Import.Store.path = '';
+ Calendar_Import.Store.id = 0;
+ Calendar_Import.Store.method = '';
+ Calendar_Import.Store.calname = '';
+ Calendar_Import.Store.progresskey = '';
+ Calendar_Import.Store.percentage = 0;
}
}
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
- FileActions.register('text/calendar','importcal', '', Calendar_Import.importdialog);
- FileActions.setDefault('text/calendar','importcal');
+ FileActions.register('text/calendar','importCalendar', '', Calendar_Import.Dialog.open);
+ FileActions.setDefault('text/calendar','importCalendar');
};
});
diff --git a/apps/calendar/js/settings.js b/apps/calendar/js/settings.js
index 03e4217573d..60741f2b6fc 100644
--- a/apps/calendar/js/settings.js
+++ b/apps/calendar/js/settings.js
@@ -34,6 +34,7 @@ $(document).ready(function(){
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'timeformat.php'), function(jsondata, status) {
$('#' + jsondata.timeformat).attr('selected',true);
$('#timeformat').chosen();
+ $('#timeformat_chzn').css('width', '100px');
});
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'gettimezonedetection.php'), function(jsondata, status){
if(jsondata.detection == 'true'){
@@ -43,6 +44,7 @@ $(document).ready(function(){
$.getJSON(OC.filePath('calendar', 'ajax/settings', 'getfirstday.php'), function(jsondata, status) {
$('#' + jsondata.firstday).attr('selected',true);
$('#firstday').chosen();
+ $('#firstday_chzn').css('width', '100px');
});
$('#cleancalendarcache').click(function(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'rescan.php'), function(){
@@ -55,7 +57,7 @@ function calendarcachecheck(){
$.getJSON(OC.filePath('calendar', 'ajax/cache', 'status.php'), function(jsondata, status) {
$('#cleancalendarcache').attr('title', jsondata.l10n.text);
if(jsondata.status == 'success'){
- $('#cleancalendarcache').css('background', '#90EE90');
+ $('#cleancalendarcache').css('background', '#F8F8F8');
$('#cleancalendarcache').css('color', '#333');
$('#cleancalendarcache').css('text-shadow', '#fff 0 1px 0');
}else{
diff --git a/apps/calendar/l10n/de.php b/apps/calendar/l10n/de.php
index f12a18baad0..33c924ac2c3 100644
--- a/apps/calendar/l10n/de.php
+++ b/apps/calendar/l10n/de.php
@@ -2,11 +2,17 @@
"No calendars found." => "Keine Kalender gefunden",
"No events found." => "Keine Termine gefunden",
"Wrong calendar" => "Falscher Kalender",
+"Import failed" => "Import fehlgeschlagen",
"New Timezone:" => "Neue Zeitzone:",
"Timezone changed" => "Zeitzone geändert",
"Invalid request" => "Fehlerhafte Anfrage",
"Calendar" => "Kalender",
-"MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}" => "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}",
+"ddd" => "ddd",
+"ddd M/d" => "ddd d.M",
+"dddd M/d" => "dddd d.M",
+"MMMM yyyy" => "MMMM yyyy",
+"MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}" => "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}",
+"dddd, MMM d, yyyy" => "dddd, d. MMM yyyy",
"Birthday" => "Geburtstag",
"Business" => "Geschäftlich",
"Call" => "Anruf",
@@ -22,7 +28,9 @@
"Projects" => "Projekte",
"Questions" => "Fragen",
"Work" => "Arbeit",
+"by" => "von",
"unnamed" => "unbenannt",
+"New Calendar" => "Neuer Kalender",
"Does not repeat" => "einmalig",
"Daily" => "täglich",
"Weekly" => "wöchentlich",
@@ -67,8 +75,26 @@
"by day and month" => "nach Tag und Monat",
"Date" => "Datum",
"Cal." => "Kal.",
+"Sun." => "So",
+"Mon." => "Mo",
+"Tue." => "Di",
+"Wed." => "Mi",
+"Thu." => "Do",
+"Fri." => "Fr",
+"Sat." => "Sa",
+"Jan." => "Jan.",
+"Feb." => "Feb.",
+"Mar." => "Mär.",
+"Apr." => "Apr.",
+"May." => "Mai",
+"Jun." => "Jun.",
+"Jul." => "Jul.",
+"Aug." => "Aug.",
+"Sep." => "Sep.",
+"Oct." => "Okt.",
+"Nov." => "Nov.",
+"Dec." => "Dez.",
"All day" => "Ganztags",
-"New Calendar" => "Neuer Kalender",
"Missing fields" => "fehlende Felder",
"Title" => "Titel",
"From Date" => "Startdatum",
@@ -132,18 +158,14 @@
"Interval" => "Intervall",
"End" => "Ende",
"occurrences" => "Termine",
-"Import a calendar file" => "Kalenderdatei Importieren",
-"Please choose the calendar" => "Bitte wählen Sie den Kalender.",
"create a new calendar" => "Neuen Kalender anlegen",
+"Import a calendar file" => "Kalenderdatei Importieren",
"Name of new calendar" => "Kalendername",
"Import" => "Importieren",
-"Importing calendar" => "Kalender wird importiert.",
-"Calendar imported successfully" => "Kalender erfolgreich importiert",
"Close Dialog" => "Dialog schließen",
"Create a new event" => "Neues Ereignis",
"View an event" => "Termin öffnen",
"No categories selected" => "Keine Kategorie ausgewählt",
-"Select category" => "Kategorie auswählen",
"of" => "von",
"at" => "um",
"Timezone" => "Zeitzone",
@@ -152,9 +174,8 @@
"24h" => "24h",
"12h" => "12h",
"First day of the week" => "erster Wochentag",
-"Calendar CalDAV syncing address:" => "Kalender CalDAV Synchronisationsadresse:",
-"Users" => "Nutzer",
-"select users" => "Nutzer auswählen",
+"Users" => "Benutzer",
+"select users" => "Benutzer auswählen",
"Editable" => "editierbar",
"Groups" => "Gruppen",
"select groups" => "Gruppen auswählen",
diff --git a/apps/calendar/l10n/it.php b/apps/calendar/l10n/it.php
index cdb2d99c82e..b91e8b0df0b 100644
--- a/apps/calendar/l10n/it.php
+++ b/apps/calendar/l10n/it.php
@@ -1,12 +1,23 @@
<?php $TRANSLATIONS = array(
+"Not all calendars are completely cached" => "Non tutti i calendari sono mantenuti completamente in cache",
+"Everything seems to be completely cached" => "Tutto sembra essere mantenuto completamente in cache",
"No calendars found." => "Nessun calendario trovato.",
"No events found." => "Nessun evento trovato.",
"Wrong calendar" => "Calendario sbagliato",
+"The file contained either no events or all events are already saved in your calendar." => "Il file non conteneva alcun evento o tutti gli eventi erano già salvati nel tuo calendario.",
+"events has been saved in the new calendar" => "gli eventi sono stati salvati nel nuovo calendario",
+"Import failed" => "Importazione non riuscita",
+"events has been saved in your calendar" => "gli eventi sono stati salvati nel tuo calendario",
"New Timezone:" => "Nuovo fuso orario:",
"Timezone changed" => "Fuso orario cambiato",
"Invalid request" => "Richiesta non valida",
"Calendar" => "Calendario",
+"ddd" => "ggg",
+"ddd M/d" => "ggg M/g",
+"dddd M/d" => "gggg M/g",
+"MMMM yyyy" => "MMMM aaaa",
"MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}" => "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}",
+"dddd, MMM d, yyyy" => "gggg, MMM g, aaaa",
"Birthday" => "Compleanno",
"Business" => "Azienda",
"Call" => "Chiama",
@@ -22,7 +33,9 @@
"Projects" => "Progetti",
"Questions" => "Domande",
"Work" => "Lavoro",
+"by" => "da",
"unnamed" => "senza nome",
+"New Calendar" => "Nuovo calendario",
"Does not repeat" => "Non ripetere",
"Daily" => "Giornaliero",
"Weekly" => "Settimanale",
@@ -67,8 +80,26 @@
"by day and month" => "per giorno e mese",
"Date" => "Data",
"Cal." => "Cal.",
+"Sun." => "Dom.",
+"Mon." => "Lun.",
+"Tue." => "Mar.",
+"Wed." => "Mer.",
+"Thu." => "Gio.",
+"Fri." => "Ven.",
+"Sat." => "Sab.",
+"Jan." => "Gen.",
+"Feb." => "Feb.",
+"Mar." => "Mar.",
+"Apr." => "Apr.",
+"May." => "Mag.",
+"Jun." => "Giu.",
+"Jul." => "Lug.",
+"Aug." => "Ago.",
+"Sep." => "Set.",
+"Oct." => "Ott.",
+"Nov." => "Nov.",
+"Dec." => "Dic.",
"All day" => "Tutti il giorno",
-"New Calendar" => "Nuovo calendario",
"Missing fields" => "Campi mancanti",
"Title" => "Titolo",
"From Date" => "Dal giorno",
@@ -132,18 +163,17 @@
"Interval" => "Intervallo",
"End" => "Fine",
"occurrences" => "occorrenze",
-"Import a calendar file" => "Importa un file di calendario",
-"Please choose the calendar" => "Scegli il calendario",
"create a new calendar" => "Crea un nuovo calendario",
+"Import a calendar file" => "Importa un file di calendario",
+"Please choose a calendar" => "Scegli un calendario",
"Name of new calendar" => "Nome del nuovo calendario",
+"Take an available name!" => "Usa un nome disponibile!",
+"A Calendar with this name already exists. If you continue anyhow, these calendars will be merged." => "Un calendario con questo nome esiste già. Se continui, i due calendari saranno uniti.",
"Import" => "Importa",
-"Importing calendar" => "Importazione del calendario in corso",
-"Calendar imported successfully" => "Calendario importato correttamente",
"Close Dialog" => "Chiudi la finestra di dialogo",
"Create a new event" => "Crea un nuovo evento",
"View an event" => "Visualizza un evento",
"No categories selected" => "Nessuna categoria selezionata",
-"Select category" => "Seleziona una categoria",
"of" => "di",
"at" => "alle",
"Timezone" => "Fuso orario",
@@ -152,7 +182,13 @@
"24h" => "24h",
"12h" => "12h",
"First day of the week" => "Primo giorno della settimana",
-"Calendar CalDAV syncing address:" => "Indirizzo sincronizzazione calendario CalDAV:",
+"Cache" => "Cache",
+"Clear cache for repeating events" => "Cancella gli eventi che si ripetono dalla cache",
+"Calendar CalDAV syncing addresses" => "Indirizzi di sincronizzazione calendari CalDAV",
+"more info" => "ulteriori informazioni",
+"Primary address (Kontact et al)" => "Indirizzo principale (Kontact e altri)",
+"iOS/OS X" => "iOS/OS X",
+"Read only iCalendar link(s)" => "Collegamento(i) iCalendar sola lettura",
"Users" => "Utenti",
"select users" => "seleziona utenti",
"Editable" => "Modificabile",
diff --git a/apps/calendar/l10n/vi.php b/apps/calendar/l10n/vi.php
new file mode 100644
index 00000000000..059b89e1635
--- /dev/null
+++ b/apps/calendar/l10n/vi.php
@@ -0,0 +1,135 @@
+<?php $TRANSLATIONS = array(
+"No calendars found." => "Không tìm thấy lịch.",
+"No events found." => "Không tìm thấy sự kiện nào",
+"Wrong calendar" => "Sai lịch",
+"New Timezone:" => "Múi giờ mới :",
+"Timezone changed" => "Thay đổi múi giờ",
+"Invalid request" => "Yêu cầu không hợp lệ",
+"Calendar" => "Lịch",
+"ddd" => "ddd",
+"ddd M/d" => "ddd M/d",
+"dddd M/d" => "dddd M/d",
+"MMMM yyyy" => "MMMM yyyy",
+"MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}" => "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}",
+"dddd, MMM d, yyyy" => "dddd, MMM d, yyyy",
+"Birthday" => "Ngày sinh nhật",
+"Business" => "Công việc",
+"Call" => "Số điện thoại",
+"Clients" => "Máy trạm",
+"Holidays" => "Ngày lễ",
+"Ideas" => "Ý tưởng",
+"Jubilee" => "Lễ kỷ niệm",
+"Meeting" => "Hội nghị",
+"Other" => "Khác",
+"Personal" => "Cá nhân",
+"Projects" => "Dự án",
+"Questions" => "Câu hỏi",
+"Work" => "Công việc",
+"New Calendar" => "Lịch mới",
+"Does not repeat" => "Không lặp lại",
+"Daily" => "Hàng ngày",
+"Weekly" => "Hàng tuần",
+"Every Weekday" => "Mỗi ngày trong tuần",
+"Bi-Weekly" => "Hai tuần một lần",
+"Monthly" => "Hàng tháng",
+"Yearly" => "Hàng năm",
+"never" => "không thay đổi",
+"by occurrences" => "bởi xuất hiện",
+"by date" => "bởi ngày",
+"by monthday" => "bởi ngày trong tháng",
+"by weekday" => "bởi ngày trong tuần",
+"Monday" => "Thứ 2",
+"Tuesday" => "Thứ 3",
+"Wednesday" => "Thứ 4",
+"Thursday" => "Thứ 5",
+"Friday" => "Thứ ",
+"Saturday" => "Thứ 7",
+"Sunday" => "Chủ nhật",
+"events week of month" => "sự kiện trong tuần của tháng",
+"first" => "đầu tiên",
+"second" => "Thứ hai",
+"third" => "Thứ ba",
+"fourth" => "Thứ tư",
+"fifth" => "Thứ năm",
+"January" => "Tháng 1",
+"February" => "Tháng 2",
+"March" => "Tháng 3",
+"April" => "Tháng 4",
+"May" => "Tháng 5",
+"June" => "Tháng 6",
+"July" => "Tháng 7",
+"August" => "Tháng 8",
+"September" => "Tháng 9",
+"October" => "Tháng 10",
+"November" => "Tháng 11",
+"December" => "Tháng 12",
+"by events date" => "Theo ngày tháng sự kiện",
+"by weeknumber(s)" => "số tuần",
+"by day and month" => "ngày, tháng",
+"Date" => "Ngày",
+"Cal." => "Cal.",
+"All day" => "Tất cả các ngày",
+"Title" => "Tiêu đề",
+"From Date" => "Từ ngày",
+"From Time" => "Từ thời gian",
+"To Date" => "Tới ngày",
+"To Time" => "Tới thời gian",
+"The event ends before it starts" => "Sự kiện này kết thúc trước khi nó bắt đầu",
+"Week" => "Tuần",
+"Month" => "Tháng",
+"List" => "Danh sách",
+"Today" => "Hôm nay",
+"Calendars" => "Lịch",
+"There was a fail, while parsing the file." => "Có một thất bại, trong khi phân tích các tập tin.",
+"Choose active calendars" => "Chọn lịch hoạt động",
+"Your calendars" => "Lịch của bạn",
+"CalDav Link" => "Liên kết CalDav ",
+"Shared calendars" => "Chia sẻ lịch",
+"No shared calendars" => "Không chia sẻ lcihj",
+"Share Calendar" => "Chia sẻ lịch",
+"Download" => "Tải về",
+"Edit" => "Chỉnh sửa",
+"Delete" => "Xóa",
+"shared with you by" => "Chia sẻ bởi",
+"New calendar" => "Lịch mới",
+"Edit calendar" => "sửa Lịch",
+"Displayname" => "Hiển thị tên",
+"Active" => "Kích hoạt",
+"Calendar color" => "Màu lịch",
+"Save" => "Lưu",
+"Submit" => "Submit",
+"Cancel" => "Hủy",
+"Edit an event" => "Sửa sự kiện",
+"Share" => "Chia sẻ",
+"Title of the Event" => "Tên sự kiện",
+"Category" => "Danh mục",
+"All Day Event" => "Sự kiện trong ngày",
+"From" => "Từ",
+"To" => "Tới",
+"Advanced options" => "Tùy chọn nâng cao",
+"Location" => "Nơi",
+"Location of the Event" => "Nơi tổ chức sự kiện",
+"Description" => "Mô tả",
+"Description of the Event" => "Mô tả sự kiện",
+"Repeat" => "Lặp lại",
+"Advanced" => "Nâng cao",
+"Select weekdays" => "Chọn ngày trong tuần",
+"Select days" => "Chọn ngày",
+"and the events day of year." => "và sự kiện của ngày trong năm",
+"and the events day of month." => "và sự kiện của một ngày trong năm",
+"Select months" => "Chọn tháng",
+"Select weeks" => "Chọn tuần",
+"and the events week of year." => "và sự kiện của tuần trong năm.",
+"create a new calendar" => "Tạo lịch mới",
+"Name of new calendar" => "Tên lịch mới",
+"Close Dialog" => "Đóng hộp thoại",
+"Create a new event" => "Tạo một sự kiện mới",
+"View an event" => "Xem một sự kiện",
+"No categories selected" => "Không danh sách nào được chọn",
+"of" => "của",
+"at" => "tại",
+"Timezone" => "Múi giờ",
+"Check always for changes of the timezone" => "Luôn kiểm tra múi giờ",
+"24h" => "24h",
+"12h" => "12h"
+);
diff --git a/apps/calendar/lib/calendar.php b/apps/calendar/lib/calendar.php
index 128b55c48e9..7778242464c 100644
--- a/apps/calendar/lib/calendar.php
+++ b/apps/calendar/lib/calendar.php
@@ -267,8 +267,42 @@ class OC_Calendar_Calendar{
'url' => OCP\Util::linkTo('calendar', 'ajax/events.php').'?calendar_id='.$calendar['id'],
'backgroundColor' => $calendar['calendarcolor'],
'borderColor' => '#888',
- 'textColor' => 'black',
+ 'textColor' => self::generateTextColor($calendar['calendarcolor']),
'cache' => true,
);
}
+
+ /*
+ * @brief checks if a calendar name is available for a user
+ * @param string $calendarname
+ * @param string $userid
+ * @return boolean
+ */
+ public static function isCalendarNameavailable($calendarname, $userid){
+ $calendars = self::allCalendars($userid);
+ foreach($calendars as $calendar){
+ if($calendar['displayname'] == $calendarname){
+ return false;
+ }
+ }
+ return true;
+ }
+
+ /*
+ * @brief generates the text color for the calendar
+ * @param string $calendarcolor rgb calendar color code in hex format (with or without the leading #)
+ * (this function doesn't pay attention on the alpha value of rgba color codes)
+ * @return boolean
+ */
+ public static function generateTextColor($calendarcolor){
+ if(substr_count($calendarcolor, '#') == 1){
+ $calendarcolor = substr($calendarcolor,1);
+ }
+ $red = hexdec(substr($calendarcolor,0,2));
+ $green = hexdec(substr($calendarcolor,2,2));
+ $blue = hexdec(substr($calendarcolor,2,2));
+ //recommendation by W3C
+ $computation = ((($red * 299) + ($green * 587) + ($blue * 114)) / 1000);
+ return ($computation > 130)?'#000000':'#FAFAFA';
+ }
}
diff --git a/apps/calendar/lib/connector_sabre.php b/apps/calendar/lib/connector_sabre.php
index 263fb7ffde5..8eea06da7e2 100644
--- a/apps/calendar/lib/connector_sabre.php
+++ b/apps/calendar/lib/connector_sabre.php
@@ -105,6 +105,9 @@ class OC_Connector_Sabre_CalDAV extends Sabre_CalDAV_Backend_Abstract {
if(!isset($newValues['timezone'])) $newValues['timezone'] = null;
if(!isset($newValues['calendarorder'])) $newValues['calendarorder'] = 0;
if(!isset($newValues['calendarcolor'])) $newValues['calendarcolor'] = null;
+ if(!is_null($newValues['calendarcolor']) && strlen($newValues['calendarcolor']) == 9){
+ $newValues['calendarcolor'] = substr($newValues['calendarcolor'], 0, 7);
+ }
return OC_Calendar_Calendar::addCalendarFromDAVData($principalUri,$calendarUri,$newValues['displayname'],$newValues['components'],$newValues['timezone'],$newValues['calendarorder'],$newValues['calendarcolor']);
}
@@ -192,7 +195,10 @@ class OC_Connector_Sabre_CalDAV extends Sabre_CalDAV_Backend_Abstract {
if(!isset($newValues['timezone'])) $newValues['timezone'] = null;
if(!isset($newValues['calendarorder'])) $newValues['calendarorder'] = null;
if(!isset($newValues['calendarcolor'])) $newValues['calendarcolor'] = null;
-
+ if(!is_null($newValues['calendarcolor']) && strlen($newValues['calendarcolor']) == 9){
+ $newValues['calendarcolor'] = substr($newValues['calendarcolor'], 0, 7);
+ }
+
OC_Calendar_Calendar::editCalendar($calendarId,$newValues['displayname'],null,$newValues['timezone'],$newValues['calendarorder'],$newValues['calendarcolor']);
return true;
diff --git a/apps/calendar/lib/import.php b/apps/calendar/lib/import.php
new file mode 100644
index 00000000000..d36891cb2b9
--- /dev/null
+++ b/apps/calendar/lib/import.php
@@ -0,0 +1,334 @@
+<?php
+/**
+ * Copyright (c) 2012 Georg Ehrke <ownclouddev@georgswebsite.de>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+/*
+ * This class does import and converts all times to the users current timezone
+ */
+class OC_Calendar_Import{
+ /*
+ * @brief counts the absolute number of parsed elements
+ */
+ private $abscount;
+
+ /*
+ * @brief var saves if the percentage should be saved with OC_Cache
+ */
+ private $cacheprogress;
+
+ /*
+ * @brief Sabre_VObject_Component_VCalendar object - for documentation see http://code.google.com/p/sabredav/wiki/Sabre_VObject_Component_VCalendar
+ */
+ private $calobject;
+
+ /*
+ * @brief var counts the number of imported elements
+ */
+ private $count;
+
+ /*
+ * @brief var to check if errors happend while initialization
+ */
+ private $error;
+
+ /*
+ * @brief var saves the ical string that was submitted with the __construct function
+ */
+ private $ical;
+
+ /*
+ * @brief calendar id for import
+ */
+ private $id;
+
+ /*
+ * @brief var saves the percentage of the import's progress
+ */
+ private $progress;
+
+ /*
+ * @brief var saves the key for the percentage of the import's progress
+ */
+ private $progresskey;
+
+ /*
+ * @brief var saves the timezone the events shell converted to
+ */
+ private $tz;
+
+ /*
+ * @brief var saves the userid
+ */
+ private $userid;
+
+ /*
+ * public methods
+ */
+
+ /*
+ * @brief does general initialization for import object
+ * @param string $calendar content of ical file
+ * @param string $tz timezone of the user
+ * @return boolean
+ */
+ public function __construct($ical){
+ $this->error = null;
+ $this->ical = $ical;
+ $this->abscount = 0;
+ $this->count = 0;
+ try{
+ $this->calobject = OC_VObject::parse($this->ical);
+ }catch(Exception $e){
+ //MISSING: write some log
+ $this->error = true;
+ return false;
+ }
+ return true;
+ }
+
+ /*
+ * @brief imports a calendar
+ * @return boolean
+ */
+ public function import(){
+ if(!$this->isValid()){
+ return false;
+ }
+ $numofcomponents = count($this->calobject->getComponents());
+ foreach($this->calobject->getComponents() as $object){
+ if(!($object instanceof Sabre_VObject_Component_VEvent) && !($object instanceof Sabre_VObject_Component_VJournal) && !($object instanceof Sabre_VObject_Component_VTodo)){
+ continue;
+ }
+ $dtend = OC_Calendar_Object::getDTEndFromVEvent($object);
+ $object->DTSTART->getDateTime()->setTimezone(new DateTimeZone($this->tz));
+ $object->DTEND->setDateTime($dtend->getDateTime(), $object->DTSTART->getDateType());
+ $object->DTEND->getDateTime()->setTimezone(new DateTimeZone($this->tz));
+ $vcalendar = $this->createVCalendar($object->serialize());
+ $insertid = OC_Calendar_Object::add($this->id, $vcalendar);
+ $this->abscount++;
+ if($this->isDuplicate($insertid)){
+ OC_Calendar_Object::delete($insertid);
+ }else{
+ $this->count++;
+ }
+ $this->updateProgress(intval(($this->abscount / $numofcomponents)*100));
+ }
+ OC_Cache::remove($this->progresskey);
+ return true;
+ }
+
+ /*
+ * @brief sets the timezone
+ * @return boolean
+ */
+ public function setTimeZone($tz){
+ $this->tz = $tz;
+ return true;
+ }
+
+ /*
+ * @brief sets the progresskey
+ * @return boolean
+ */
+ public function setProgresskey($progresskey){
+ $this->progresskey = $progresskey;
+ return true;
+ }
+
+ /*
+ * @brief checks if something went wrong while initialization
+ * @return boolean
+ */
+ public function isValid(){
+ if(is_null($this->error)){
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @brief returns the percentage of progress
+ * @return integer
+ */
+ public function getProgress(){
+ return $this->progress;
+ }
+
+ /*
+ * @brief enables the cache for the percentage of progress
+ * @return boolean
+ */
+ public function enableProgressCache(){
+ $this->cacheprogress = true;
+ return true;
+ }
+
+ /*
+ * @brief disables the cache for the percentage of progress
+ * @return boolean
+ */
+ public function disableProgressCache(){
+ $this->cacheprogress = false;
+ return false;
+ }
+
+ /*
+ * @brief generates a new calendar name
+ * @return string
+ */
+ public function createCalendarName(){
+ $calendars = OC_Calendar_Calendar::allCalendars($this->userid);
+ $calendarname = $guessedcalendarname = !is_null($this->guessCalendarName())?($this->guessCalendarName()):(OC_Calendar_App::$l10n->t('New Calendar'));
+ $i = 1;
+ while(!OC_Calendar_Calendar::isCalendarNameavailable($calendarname, $this->userid)){
+ $calendarname = $guessedcalendarname . ' (' . $i . ')';
+ $i++;
+ }
+ return $calendarname;
+ }
+
+ /*
+ * @brief generates a new calendar color
+ * @return string
+ */
+ public function createCalendarColor(){
+ if(is_null($this->guessCalendarColor())){
+ return '#9fc6e7';
+ }
+ return $this->guessCalendarColor();
+ }
+
+ /*
+ * @brief sets the id for the calendar
+ * @param integer $id of the calendar
+ * @return boolean
+ */
+ public function setCalendarID($id){
+ $this->id = $id;
+ return true;
+ }
+
+ /*
+ * @brief sets the userid to import the calendar
+ * @param string $id of the user
+ * @return boolean
+ */
+ public function setUserID($userid){
+ $this->userid = $userid;
+ return true;
+ }
+
+ /*
+ * @brief returns the private
+ * @param string $id of the user
+ * @return boolean
+ */
+ public function getCount(){
+ return $this->count;
+ }
+
+ /*
+ * private methods
+ */
+
+ /*
+ * @brief generates an unique ID
+ * @return string
+ */
+ //private function createUID(){
+ // return substr(md5(rand().time()),0,10);
+ //}
+
+ /*
+ * @brief checks is the UID is already in use for another event
+ * @param string $uid uid to check
+ * @return boolean
+ */
+ //private function isUIDAvailable($uid){
+ //
+ //}
+
+ /*
+ * @brief generates a proper VCalendar string
+ * @param string $vobject
+ * @return string
+ */
+ private function createVCalendar($vobject){
+ if(is_object($vobject)){
+ $vobject = @$vobject->serialize();
+ }
+ $vcalendar = "BEGIN:VCALENDAR\nVERSION:2.0\nPRODID:ownCloud Calendar " . OCP\App::getAppVersion('calendar') . "\n";
+ $vcalendar .= $vobject;
+ $vcalendar .= "END:VCALENDAR";
+ return $vcalendar;
+ }
+
+ /*
+ * @brief checks if an event already exists in the user's calendars
+ * @param integer $insertid id of the new object
+ * @return boolean
+ */
+ private function isDuplicate($insertid){
+ $newobject = OC_Calendar_Object::find($insertid);
+ $stmt = OCP\DB::prepare('SELECT COUNT(*) as count FROM *PREFIX*calendar_objects WHERE objecttype=? AND startdate=? AND enddate=? AND repeating=? AND summary=? AND calendardata=?');
+ $result = $stmt->execute(array($newobject['objecttype'],$newobject['startdate'],$newobject['enddate'],$newobject['repeating'],$newobject['summary'],$newobject['calendardata']));
+ $result = $result->fetchRow();
+ if($result['count'] >= 2){
+ return true;
+ }
+ return false;
+ }
+
+ /*
+ * @brief updates the progress var
+ * @param integer $percentage
+ * @return boolean
+ */
+ private function updateProgress($percentage){
+ $this->progress = $percentage;
+ if($this->cacheprogress){
+ OC_Cache::set($this->progresskey, $this->progress, 300);
+ }
+ return true;
+ }
+
+ /*
+ * public methods for (pre)rendering of X-... Attributes
+ */
+
+ /*
+ * @brief guesses the calendar color
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarColor(){
+ if(!is_null($this->calobject->__get('X-APPLE-CALENDAR-COLOR'))){
+ return $this->calobject->__get('X-APPLE-CALENDAR-COLOR');
+ }
+ return null;
+ }
+
+ /*
+ * @brief guesses the calendar description
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarDescription(){
+ if(!is_null($this->calobject->__get('X-WR-CALDESC'))){
+ return $this->calobject->__get('X-WR-CALDESC');
+ }
+ return null;
+ }
+
+ /*
+ * @brief guesses the calendar name
+ * @return mixed - string or boolean
+ */
+ public function guessCalendarName(){
+ if(!is_null($this->calobject->__get('X-WR-CALNAME'))){
+ return $this->calobject->__get('X-WR-CALNAME');
+ }
+ return null;
+ }
+}
diff --git a/apps/calendar/templates/part.import.php b/apps/calendar/templates/part.import.php
index 70ff9612157..2ce3cc34239 100644
--- a/apps/calendar/templates/part.import.php
+++ b/apps/calendar/templates/part.import.php
@@ -1,30 +1,58 @@
-<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file"); ?>">
-<div id="form_container">
-<input type="hidden" id="filename" value="<?php echo $_['filename'];?>">
-<input type="hidden" id="path" value="<?php echo $_['path'];?>">
-<input type="hidden" id="progresskey" value="<?php echo rand() ?>">
-<p style="text-align:center;"><b><?php echo $l->t('Please choose the calendar'); ?></b></p>
-<select style="width:100%;" id="calendar" name="calendar">
<?php
+//Prerendering for iCalendar file
+$file = OC_Filesystem::file_get_contents($_['path'] . '/' . $_['filename']);
+if(!$file){
+ OCP\JSON::error(array('error'=>'404'));
+}
+$import = new OC_Calendar_Import($file);
+$import->setUserID(OCP\User::getUser());
+$newcalendarname = strip_tags($import->createCalendarName());
+$guessedcalendarname = strip_tags($import->guessCalendarName());
+$calendarcolor = strip_tags($import->createCalendarColor());
+//loading calendars for select box
$calendar_options = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser());
$calendar_options[] = array('id'=>'newcal', 'displayname'=>$l->t('create a new calendar'));
-for($i = 0;$i<count($calendar_options);$i++){
- $calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
-}
-echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
+$defaultcolors = OC_Calendar_Calendar::getCalendarColorOptions();
?>
-</select>
-<div id="newcalform" style="display: none;">
- <input type="text" style="width: 97%;" placeholder="<?php echo $l->t('Name of new calendar'); ?>" id="newcalendar" name="newcalendar">
-</div>
-<input type="button" value="<?php echo $l->t("Import");?>!" id="startimport">
-</div>
-<div id="progressbar_container" style="display: none">
-<p style="text-align:center;"><b><?php echo $l->t('Importing calendar'); ?></b></p>
-<div id="progressbar"></div>
-<div id="import_done" style="display: none;">
-<p style="text-align:center;"><b><?php echo $l->t('Calendar imported successfully'); ?></b></p>
-<input type="button" value="<?php echo $l->t('Close Dialog'); ?>" id="import_done_button">
+<div id="calendar_import_dialog" title="<?php echo $l->t("Import a calendar file");?>">
+<div id="calendar_import_form">
+ <form>
+ <input type="hidden" id="calendar_import_filename" value="<?php echo $_['filename'];?>">
+ <input type="hidden" id="calendar_import_path" value="<?php echo $_['path'];?>">
+ <input type="hidden" id="calendar_import_progresskey" value="<?php echo rand() ?>">
+ <input type="hidden" id="calendar_import_availablename" value="<?php echo $newcalendarname ?>">
+ <div id="calendar_import_form_message"><?php echo $l->t('Please choose a calendar'); ?></div>
+ <select style="width:100%;" id="calendar_import_calendar" name="calendar_import_calendar">
+ <?php
+ for($i = 0;$i<count($calendar_options);$i++){
+ $calendar_options[$i]['displayname'] = $calendar_options[$i]['displayname'];
+ }
+ echo OCP\html_select_options($calendar_options, $calendar_options[0]['id'], array('value'=>'id', 'label'=>'displayname'));
+ ?>
+ </select>
+ <br><br>
+ <div id="calendar_import_newcalform">
+ <input id="calendar_import_newcalendar_color" class="color-picker" type="hidden" size="6" value="<?php echo substr($calendarcolor,1); ?>">
+ <input id="calendar_import_newcalendar" class="" type="text" placeholder="<?php echo $l->t('Name of new calendar'); ?>" value="<?php echo $guessedcalendarname ?>"><br>
+ <div id="calendar_import_defaultcolors">
+ <?php
+ foreach($defaultcolors as $color){
+ echo '<span class="calendar-colorpicker-color" rel="' . $color . '" style="background-color: ' . $color . ';"></span>';
+ }
+ ?>
+ </div>
+ <!--<input id="calendar_import_generatename" type="button" class="button" value="<?php echo $l->t('Take an available name!'); ?>"><br>-->
+ <div id="calendar_import_mergewarning" class="hint"><?php echo $l->t('A Calendar with this name already exists. If you continue anyhow, these calendars will be merged.'); ?></div>
+ </div>
+ <input id="calendar_import_submit" type="button" class="button" value="&raquo; <?php echo $l->t('Import'); ?> &raquo;" id="startimport">
+ <form>
</div>
+<div id="calendar_import_process">
+ <div id="calendar_import_process_message"></div>
+ <div id="calendar_import_progressbar"></div>
+ <br>
+ <div id="calendar_import_status" class="hint"></div>
+ <br>
+ <input id="calendar_import_done" type="button" value="<?php echo $l->t('Close Dialog'); ?>">
</div>
</div> \ No newline at end of file
diff --git a/apps/contacts/ajax/loadphoto.php b/apps/contacts/ajax/loadphoto.php
deleted file mode 100644
index be924b5db4d..00000000000
--- a/apps/contacts/ajax/loadphoto.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-/**
- * ownCloud - Addressbook
- *
- * @author Thomas Tanghus
- * @copyright 2012 Thomas Tanghus <thomas@tanghus.net>
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-// Check if we are a user
-OCP\JSON::checkLoggedIn();
-OCP\JSON::checkAppEnabled('contacts');
-
-require_once 'loghandler.php';
-
-$id = isset($_GET['id']) ? $_GET['id'] : '';
-$refresh = isset($_GET['refresh']) ? true : false;
-
-if($id == '') {
- bailOut(OC_Contacts_App::$l10n->t('Missing contact id.'));
-}
-
-$checksum = '';
-$vcard = OC_Contacts_App::getContactVCard( $id );
-foreach($vcard->children as $property){
- if($property->name == 'PHOTO') {
- $checksum = md5($property->serialize());
- break;
- }
-}
-
-OCP\JSON::success(array('data' => array('checksum'=>$checksum)));
-
diff --git a/apps/contacts/css/contacts.css b/apps/contacts/css/contacts.css
index 927e7309807..ddae27da211 100644
--- a/apps/contacts/css/contacts.css
+++ b/apps/contacts/css/contacts.css
@@ -125,3 +125,12 @@ input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.typelist[type="button"] { float: left; max-width: 10em; border: 0; background-color: #fff; color: #bbb} /* for multiselect */
.typelist[type="button"]:hover { color: #777; } /* for multiselect */
.addresslist { clear: both; font-weight: bold; }
+#ninjahelp { position: absolute; bottom: 0; left: 0; right: 0; padding: 1em; margin: 1em; border: thin solid #eee; border-radius: 5px; background-color: #DBDBDB; opacity: 0.9; }
+#ninjahelp .close { position: absolute; top: 5px; right: 5px; height: 20px; width: 20px; }
+#ninjahelp h2, .help-section h3 { width: 100%; font-weight: bold; text-align: center; }
+#ninjahelp h2 { font-size: 1.4em; }
+.help-section { width: 45%; min-width: 35em; float: left; }
+.help-section h3 { font-size: 1.2em; }
+.help-section dl { width: 100%; float: left; clear: right; margin: 0; padding: 0; cursor: normal; }
+.help-section dt { display: table-cell; clear: left; float: left; width: 35%; margin: 0; padding: 0.2em; text-align: right; text-overflow: ellipsis; vertical-align: text-bottom; font-weight: bold: }
+.help-section dd { display: table-cell; clear: right; float: left; margin: 0; padding: 0.2em; white-space: nowrap; vertical-align: text-bottom; }
diff --git a/apps/contacts/js/contacts.js b/apps/contacts/js/contacts.js
index 337f51839dc..4c6c8bf3d93 100644
--- a/apps/contacts/js/contacts.js
+++ b/apps/contacts/js/contacts.js
@@ -21,27 +21,31 @@ Contacts={
* data: An object that will be passed as argument to the timeouthandler and clickhandler functions.
*/
notify:function(params) {
- var notifier = $('#notification');
- notifier.text(params.message);
- notifier.fadeIn();
+ self = this;
+ if(!self.notifier) {
+ self.notifier = $('#notification');
+ }
+ self.notifier.text(params.message);
+ self.notifier.fadeIn();
+ self.notifier.on('click', function() { $(this).fadeOut();});
var timer = setTimeout(function() {
- notifier.fadeOut();
+ self.notifier.fadeOut();
if(params.timeouthandler && $.isFunction(params.timeouthandler)) {
- params.timeouthandler(notifier.data(dataid));
- notifier.off('click');
- notifier.data(dataid, null);
+ params.timeouthandler(self.notifier.data(dataid));
+ self.notifier.off('click');
+ self.notifier.removeData(dataid);
}
}, params.timeout && $.isNumeric(params.timeout) ? parseInt(params.timeout)*1000 : 10000);
var dataid = timer.toString();
if(params.data) {
- notifier.data(dataid, params.data);
+ self.notifier.data(dataid, params.data);
}
if(params.clickhandler && $.isFunction(params.clickhandler)) {
- notifier.on('click', function() {
+ self.notifier.on('click', function() {
clearTimeout(timer);
- notifier.off('click');
- params.clickhandler(notifier.data(dataid));
- notifier.data(dataid, null);
+ self.notifier.off('click');
+ params.clickhandler(self.notifier.data(dataid));
+ self.notifier.removeData(dataid);
});
}
},
@@ -218,11 +222,7 @@ Contacts={
var item = $('.contacts li[data-id="'+Contacts.UI.Card.id+'"]').detach();
$(item).find('a').html(name);
Contacts.UI.Card.fn = name;
- Contacts.UI.Contacts.insertContact({
- contactlist:$('#contacts ul[data-id="'+Contacts.UI.Card.bookid+'"]'),
- contacts:$('#contacts ul[data-id="'+Contacts.UI.Card.bookid+'"] li'),
- contact:item,
- });
+ Contacts.UI.Contacts.insertContact({contact:item});
Contacts.UI.Contacts.scrollTo(Contacts.UI.Card.id);
});
@@ -295,16 +295,6 @@ Contacts={
$('#contacts_propertymenu_dropdown a').keydown(propertyMenuItem);
},
Card:{
- id:'',
- fn:'',
- fullname:'',
- shortname:'',
- famname:'',
- givname:'',
- addname:'',
- honpre:'',
- honsuf:'',
- data:undefined,
update:function(params) { // params {cid:int, aid:int}
if(!params) { params = {}; }
$('#contacts li,#contacts h3').removeClass('active');
@@ -321,10 +311,11 @@ Contacts={
newid = parseInt($('#contacts').find('li[data-bookid="'+bookid+'"]').first().data('id'));
} else if(parseInt(params.cid) && !parseInt(params.aid)) {
newid = parseInt(params.cid);
- var listitem = $('#contacts li[data-id="'+newid+'"]');
+ var listitem = Contacts.UI.Contacts.getContact(newid); //$('#contacts li[data-id="'+newid+'"]');
console.log('Is contact in list? ' + listitem.length);
if(listitem.length) {
- bookid = parseInt($('#contacts li[data-id="'+newid+'"]').data('bookid'));
+ //bookid = parseInt($('#contacts li[data-id="'+newid+'"]').data('bookid'));
+ bookid = parseInt(Contacts.UI.Contacts.getContact(newid).data('bookid'));
} else { // contact isn't in list yet.
bookid = 'unknown';
}
@@ -412,19 +403,7 @@ Contacts={
$.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
if(jsondata.status == 'success'){
Contacts.UI.Card.loadContact(jsondata.data, aid);
- $('#contacts .active').removeClass('active');
- var item = $('<li data-id="'+jsondata.data.id+'" class="active"><a href="index.php?id='+jsondata.data.id+'" style="background: url('+OC.filePath('contacts', '', 'thumbnail.php')+'?id='+jsondata.data.id+') no-repeat scroll 0% 0% transparent;">'+Contacts.UI.Card.fn+'</a></li>');
- var added = false;
- $('#contacts ul[data-id="'+aid+'"] li').each(function(){
- if ($(this).text().toLowerCase() > Contacts.UI.Card.fn.toLowerCase()) {
- $(this).before(item).fadeIn('fast');
- added = true;
- return false;
- }
- });
- if(!added) {
- $('#contacts ul[data-id="'+aid+'"]').append(item);
- }
+ var item = Contacts.UI.Contacts.insertContact({data:jsondata.data});
if(isnew) { // add some default properties
Contacts.UI.Card.addProperty('EMAIL');
Contacts.UI.Card.addProperty('TEL');
@@ -461,9 +440,14 @@ Contacts={
}
},
delayedDelete:function() {
+ /* TODO:
+ $(window).unload(function() {
+ deleteFilesInQueue();
+ });
+ */
$('#contacts_deletecard').tipsy('hide');
var newid = '', bookid;
- var curlistitem = $('#contacts li[data-id="'+Contacts.UI.Card.id+'"]');
+ var curlistitem = Contacts.UI.Contacts.getContact(this.id);
curlistitem.removeClass('active');
var newlistitem = curlistitem.prev('li');
if(!newlistitem) {
@@ -474,19 +458,21 @@ Contacts={
newid = newlistitem.data('id');
bookid = newlistitem.data('bookid');
}
- $('#rightcontent').data('id',newid);
- this.id = this.fn = this.fullname = this.shortname = this.famname = this.givname = this.addname = this.honpre = this.honsuf = '';
- this.data = undefined;
+ $('#rightcontent').data('id', newid);
+
+ with(this) {
+ delete id; delete fn; delete fullname; delete shortname; delete famname;
+ delete givname; delete addname; delete honpre; delete honsuf; delete data;
+ }
- if($('.contacts li').length > 0) { // Load first in list.
+ if($('.contacts li').length > 0) {
Contacts.UI.Card.update({cid:newid, aid:bookid});
} else {
// load intro page
$.getJSON(OC.filePath('contacts', 'ajax', 'loadintro.php'),{},function(jsondata){
if(jsondata.status == 'success'){
id = '';
- $('#rightcontent').data('id','');
- $('#rightcontent').html(jsondata.data.page);
+ $('#rightcontent').html(jsondata.data.page).removeData('id');
}
else{
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
@@ -526,21 +512,22 @@ Contacts={
this.loadAddresses();
this.loadSingleProperties();
Contacts.UI.loadListHandlers();
+ var note = $('#note');
if(this.data.NOTE) {
- $('#note').data('checksum', this.data.NOTE[0]['checksum']);
- var note = $('#note').find('textarea');
+ note.data('checksum', this.data.NOTE[0]['checksum']);
+ var textarea = note.find('textarea');
var txt = this.data.NOTE[0]['value'];
var nheight = txt.split('\n').length > 4 ? txt.split('\n').length+2 : 5;
- note.css('min-height', nheight+'em');
- note.attr('rows', nheight);
- note.val(txt);
- $('#note').show();
- note.expandingTextarea();
+ textarea.css('min-height', nheight+'em');
+ textarea.attr('rows', nheight);
+ textarea.val(txt);
+ note.show();
+ textarea.expandingTextarea();
$('#contacts_propertymenu_dropdown a[data-type="NOTE"]').parent().hide();
} else {
- $('#note').data('checksum', '');
- $('#note').find('textarea').val('');
- $('#note').hide();
+ note.removeData('checksum');
+ note.find('textarea').val('');
+ note.hide();
$('#contacts_propertymenu_dropdown a[data-type="NOTE"]').parent().show();
}
},
@@ -566,10 +553,11 @@ Contacts={
var val = $.datepicker.parseDate('yy-mm-dd', value.substring(0, 10));
value = $.datepicker.formatDate('dd-mm-yy', val);
}
- $('#contact_identity').find('#'+propname.toLowerCase()).val(value);
- $('#contact_identity').find('#'+propname.toLowerCase()+'_value').data('checksum', checksum);
- $('#contact_identity').find('#'+propname.toLowerCase()+'_label').show();
- $('#contact_identity').find('#'+propname.toLowerCase()+'_value').show();
+ var identcontainer = $('#contact_identity');
+ identcontainer.find('#'+propname.toLowerCase()).val(value);
+ identcontainer.find('#'+propname.toLowerCase()+'_value').data('checksum', checksum);
+ identcontainer.find('#'+propname.toLowerCase()+'_label').show();
+ identcontainer.find('#'+propname.toLowerCase()+'_value').show();
} else {
$('#contacts_propertymenu_dropdown a[data-type="'+propname+'"]').parent().show();
}
@@ -584,8 +572,12 @@ Contacts={
$(this).find('input').val('');
}
});
- this.fn = ''; this.fullname = ''; this.givname = ''; this.famname = ''; this.addname = ''; this.honpre = ''; this.honsuf = '';
- var narray = undefined;
+
+ with(this) {
+ delete fn; delete fullname; delete givname; delete famname;
+ delete addname; delete honpre; delete honsuf;
+ }
+
if(this.data.FN) {
this.fn = this.data.FN[0]['value'];
}
@@ -769,17 +761,9 @@ Contacts={
},
addProperty:function(type){
switch (type) {
- case 'PHOTO':
- this.loadPhoto(true);
- $('#file_upload_form').show();
- $('#contacts_propertymenu_dropdown a[data-type="'+type+'"]').parent().hide();
- $('#file_upload_start').trigger('click');
- break;
case 'NOTE':
- $('#note').show();
$('#contacts_propertymenu_dropdown a[data-type="'+type+'"]').parent().hide();
- $('#note').find('textarea').expandingTextarea();
- $('#note').find('textarea').focus();
+ $('#note').find('textarea').expandingTextarea().show().focus();
break;
case 'EMAIL':
if($('#emaillist>li').length == 1) {
@@ -834,8 +818,7 @@ Contacts={
}
} else {
$('dl dt[data-element="'+proptype+'"],dd[data-element="'+proptype+'"]').hide();
- $('dl dd[data-element="'+proptype+'"]').data('checksum', '');
- $('dl dd[data-element="'+proptype+'"]').find('input').val('');
+ $('dl dd[data-element="'+proptype+'"]').data('checksum', '').find('input').val('');
}
$('#contacts_propertymenu_dropdown a[data-type="'+proptype+'"]').parent().show();
Contacts.UI.loading(obj, false);
@@ -862,14 +845,14 @@ Contacts={
}
}
},
- editName:function(){
+ editName:function() {
var params = {id: this.id};
/* Initialize the name edit dialog */
- if($('#edit_name_dialog').dialog('isOpen') == true){
+ if($('#edit_name_dialog').dialog('isOpen') == true) {
$('#edit_name_dialog').dialog('moveToTop');
- }else{
- $.getJSON(OC.filePath('contacts', 'ajax', 'editname.php'),{id: this.id},function(jsondata){
- if(jsondata.status == 'success'){
+ } else {
+ $.getJSON(OC.filePath('contacts', 'ajax', 'editname.php'),{id: this.id},function(jsondata) {
+ if(jsondata.status == 'success') {
$('body').append('<div id="name_dialog"></div>');
$('#name_dialog').html(jsondata.data.page).find('#edit_name_dialog' ).dialog({
modal: true,
@@ -941,10 +924,11 @@ Contacts={
loadAddresses:function(){
$('#addresses').hide();
$('#addressdisplay dl.propertycontainer').remove();
+ var addresscontainer = $('#addressdisplay');
for(var adr in this.data.ADR) {
- $('#addressdisplay dl').first().clone().insertAfter($('#addressdisplay dl').last()).show();
- $('#addressdisplay dl').last().removeClass('template').addClass('propertycontainer');
- $('#addressdisplay dl').last().data('checksum', this.data.ADR[adr]['checksum']);
+ addresscontainer.find('dl').first().clone().insertAfter($('#addressdisplay dl').last()).show();
+ addresscontainer.find('dl').last().removeClass('template').addClass('propertycontainer');
+ addresscontainer.find('dl').last().data('checksum', this.data.ADR[adr]['checksum']);
var adrarray = this.data.ADR[adr]['value'];
var adrtxt = '';
if(adrarray[0] && adrarray[0].length > 0) {
@@ -956,7 +940,7 @@ Contacts={
if(adrarray[2] && adrarray[2].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[2].strip_tags() + '</li>';
}
- if((adrarray[3] && adrarray[5]) && adrarray[3].length > 0 || adrarray[5].length > 0) {
+ if((3 in adrarray && 5 in adrarray) && adrarray[3].length > 0 || adrarray[5].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[5].strip_tags() + ' ' + adrarray[3].strip_tags() + '</li>';
}
if(adrarray[4] && adrarray[4].length > 0) {
@@ -965,7 +949,7 @@ Contacts={
if(adrarray[6] && adrarray[6].length > 0) {
adrtxt = adrtxt + '<li>' + adrarray[6].strip_tags() + '</li>';
}
- $('#addressdisplay dl').last().find('.addresslist').html(adrtxt);
+ addresscontainer.find('dl').last().find('.addresslist').html(adrtxt);
var types = new Array();
var ttypes = new Array();
for(var param in this.data.ADR[adr]['parameters']) {
@@ -974,12 +958,12 @@ Contacts={
ttypes.push(this.data.ADR[adr]['parameters'][param]);
}
}
- $('#addressdisplay dl').last().find('.adr_type_label').text(types.join('/'));
- $('#addressdisplay dl').last().find('.adr_type').val(ttypes.join(','));
- $('#addressdisplay dl').last().find('.adr').val(adrarray.join(';'));
- $('#addressdisplay dl').last().data('checksum', this.data.ADR[adr]['checksum']);
+ addresscontainer.find('dl').last().find('.adr_type_label').text(types.join('/'));
+ addresscontainer.find('dl').last().find('.adr_type').val(ttypes.join(','));
+ addresscontainer.find('dl').last().find('.adr').val(adrarray.join(';'));
+ addresscontainer.find('dl').last().data('checksum', this.data.ADR[adr]['checksum']);
}
- if($('#addressdisplay dl').length > 1) {
+ if(addresscontainer.find('dl').length > 1) {
$('#addresses').show();
$('#contact_communication').show();
}
@@ -1024,9 +1008,6 @@ Contacts={
close : function(event, ui) {
$(this).dialog('destroy').remove();
$('#address_dialog').remove();
- if(isnew) {
- container.remove();
- }
},
open : function(event, ui) {
$( "#adr_city" ).autocomplete({
@@ -1065,7 +1046,7 @@ Contacts={
$( this ).removeClass( "ui-corner-top" ).addClass( "ui-corner-all" );
}
});
- $( "#adr_country" ).autocomplete({
+ $('#adr_country').autocomplete({
source: function( request, response ) {
$.ajax({
url: "http://ws.geonames.org/searchJSON",
@@ -1116,15 +1097,23 @@ Contacts={
saveAddress:function(dlg, obj, isnew){
if(isnew) {
container = $('#addressdisplay dl').last();
- obj = $('#addressdisplay dl:last-child').find('input').first();
+ obj = container.find('input').first();
} else {
checksum = Contacts.UI.checksumFor(obj);
container = Contacts.UI.propertyContainerFor(obj);
}
- var adr = new Array($(dlg).find('#adr_pobox').val().strip_tags(),$(dlg).find('#adr_extended').val().strip_tags(),$(dlg).find('#adr_street').val().strip_tags(),$(dlg).find('#adr_city').val().strip_tags(),$(dlg).find('#adr_region').val().strip_tags(),$(dlg).find('#adr_zipcode').val().strip_tags(),$(dlg).find('#adr_country').val().strip_tags());
- $(container).find('.adr').val(adr.join(';'));
- $(container).find('.adr_type').val($(dlg).find('#adr_type').val());
- $(container).find('.adr_type_label').html(t('contacts',ucwords($(dlg).find('#adr_type').val().toLowerCase())));
+ var adr = new Array(
+ $(dlg).find('#adr_pobox').val().strip_tags(),
+ $(dlg).find('#adr_extended').val().strip_tags(),
+ $(dlg).find('#adr_street').val().strip_tags(),
+ $(dlg).find('#adr_city').val().strip_tags(),
+ $(dlg).find('#adr_region').val().strip_tags(),
+ $(dlg).find('#adr_zipcode').val().strip_tags(),
+ $(dlg).find('#adr_country').val().strip_tags()
+ );
+ container.find('.adr').val(adr.join(';'));
+ container.find('.adr_type').val($(dlg).find('#adr_type').val());
+ container.find('.adr_type_label').html(t('contacts',ucwords($(dlg).find('#adr_type').val().toLowerCase())));
Contacts.UI.Card.saveProperty($(container).find('input').first());
var adrtxt = '';
if(adr[0].length > 0) {
@@ -1145,7 +1134,7 @@ Contacts={
if(adr[6].length > 0) {
adrtxt = adrtxt + '<li>' + adr[6] + '</li>';
}
- $(container).find('.addresslist').html(adrtxt);
+ container.find('.addresslist').html(adrtxt);
},
uploadPhoto:function(filelist) {
if(!filelist) {
@@ -1172,24 +1161,25 @@ Contacts={
form.submit();
}
},
- loadPhotoHandlers:function(){
- $('#phototools li a').tipsy('hide');
- $('#phototools li a').tipsy();
+ loadPhotoHandlers:function() {
+ var phototools = $('#phototools');
+ phototools.find('li a').tipsy('hide');
+ phototools.find('li a').tipsy();
if(this.data.PHOTO) {
- $('#phototools .delete').click(function() {
+ phototools.find('.delete').click(function() {
$(this).tipsy('hide');
Contacts.UI.Card.deleteProperty($('#contacts_details_photo'), 'single');
$(this).hide();
});
- $('#phototools .edit').click(function() {
+ phototools.find('.edit').click(function() {
$(this).tipsy('hide');
Contacts.UI.Card.editCurrentPhoto();
});
- $('#phototools .delete').show();
- $('#phototools .edit').show();
+ phototools.find('.delete').show();
+ phototools.find('.edit').show();
} else {
- $('#phototools .delete').hide();
- $('#phototools .edit').hide();
+ phototools.find('.delete').hide();
+ phototools.find('.edit').hide();
}
},
cloudPhotoSelected:function(path){
@@ -1210,28 +1200,18 @@ Contacts={
$('#phototools li a').tipsy('hide');
var wrapper = $('#contacts_details_photo_wrapper');
wrapper.addClass('loading').addClass('wait');
-
- var img = new Image();
- $(img).load(function () {
+ delete this.photo;
+ this.photo = new Image();
+ $(this.photo).load(function () {
$('img.contacts_details_photo').remove()
- $(this).addClass('contacts_details_photo').hide();
+ $(this).addClass('contacts_details_photo');
wrapper.removeClass('loading').removeClass('wait');
$(this).insertAfter($('#phototools')).fadeIn();
}).error(function () {
// notify the user that the image could not be loaded
Contacts.UI.notify({message:t('contacts','Error loading profile picture.')});
}).attr('src', OC.linkTo('contacts', 'photo.php')+'?id='+self.id+refreshstr);
-
- $.getJSON(OC.filePath('contacts', 'ajax', 'loadphoto.php'),{'id':this.id, 'refresh': refresh},function(jsondata){
- if(jsondata.status == 'success'){
- $('#contacts_details_photo_wrapper').data('checksum', jsondata.data.checksum);
- Contacts.UI.Card.loadPhotoHandlers();
- }
- else{
- OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
- }
- });
- $('#file_upload_form').show();
+ this.loadPhotoHandlers()
},
editCurrentPhoto:function(){
$.getJSON(OC.filePath('contacts', 'ajax', 'currentphoto.php'),{'id':this.id},function(jsondata){
@@ -1285,10 +1265,11 @@ Contacts={
},
addMail:function() {
//alert('addMail');
- $('#emaillist li.template:first-child').clone(true).appendTo($('#emaillist')).show().find('a .tip').tipsy();
- $('#emaillist li.template:last-child').find('select').addClass('contacts_property');
- $('#emaillist li.template:last-child').removeClass('template').addClass('propertycontainer');
- $('#emaillist li:last-child').find('input[type="email"]').focus();
+ var emaillist = $('#emaillist');
+ emaillist.find('li.template:first-child').clone(true).appendTo(emaillist).show().find('a .tip').tipsy();
+ emaillist.find('li.template:last-child').find('select').addClass('contacts_property');
+ emaillist.find('li.template:last-child').removeClass('template').addClass('propertycontainer');
+ emaillist.find('li:last-child').find('input[type="email"]').focus();
return false;
},
loadMails:function() {
@@ -1324,35 +1305,37 @@ Contacts={
return false;
},
addPhone:function() {
- $('#phonelist li.template:first-child').clone(true).appendTo($('#phonelist')); //.show();
- $('#phonelist li.template:last-child').find('select').addClass('contacts_property');
- $('#phonelist li.template:last-child').removeClass('template').addClass('propertycontainer');
- $('#phonelist li:last-child').find('input[type="text"]').focus();
- $('#phonelist li:last-child').find('select').multiselect({
+ var phonelist = $('#phonelist');
+ phonelist.find('li.template:first-child').clone(true).appendTo(phonelist); //.show();
+ phonelist.find('li.template:last-child').find('select').addClass('contacts_property');
+ phonelist.find('li.template:last-child').removeClass('template').addClass('propertycontainer');
+ phonelist.find('li:last-child').find('input[type="text"]').focus();
+ phonelist.find('li:last-child').find('select').multiselect({
noneSelectedText: t('contacts', 'Select type'),
header: false,
selectedList: 4,
classes: 'typelist'
});
- $('#phonelist li:last-child').show();
+ phonelist.find('li:last-child').show();
return false;
},
loadPhones:function() {
$('#phones').hide();
$('#phonelist li.propertycontainer').remove();
+ var phonelist = $('#phonelist');
for(var phone in this.data.TEL) {
this.addPhone();
- $('#phonelist li:last-child').find('select').multiselect('destroy');
- $('#phonelist li:last-child').data('checksum', this.data.TEL[phone]['checksum'])
- $('#phonelist li:last-child').find('input[type="text"]').val(this.data.TEL[phone]['value']);
+ phonelist.find('li:last-child').find('select').multiselect('destroy');
+ phonelist.find('li:last-child').data('checksum', this.data.TEL[phone]['checksum'])
+ phonelist.find('li:last-child').find('input[type="text"]').val(this.data.TEL[phone]['value']);
for(var param in this.data.TEL[phone]['parameters']) {
if(param.toUpperCase() == 'PREF') {
- $('#phonelist li:last-child').find('input[type="checkbox"]').attr('checked', 'checked');
+ phonelist.find('li:last-child').find('input[type="checkbox"]').attr('checked', 'checked');
}
else if(param.toUpperCase() == 'TYPE') {
for(ptype in this.data.TEL[phone]['parameters'][param]) {
var pt = this.data.TEL[phone]['parameters'][param][ptype];
- $('#phonelist li:last-child').find('select option').each(function(){
+ phonelist.find('li:last-child').find('select option').each(function(){
//if ($(this).val().toUpperCase() == pt.toUpperCase()) {
if ($.inArray($(this).val().toUpperCase(), pt.toUpperCase().split(',')) > -1) {
$(this).attr('selected', 'selected');
@@ -1361,14 +1344,14 @@ Contacts={
}
}
}
- $('#phonelist li:last-child').find('select').multiselect({
- noneSelectedText: t('contacts', 'Select type'),
- header: false,
- selectedList: 4,
- classes: 'typelist'
- });
+ phonelist.find('li:last-child').find('select').multiselect({
+ noneSelectedText: t('contacts', 'Select type'),
+ header: false,
+ selectedList: 4,
+ classes: 'typelist'
+ });
}
- if($('#phonelist li').length > 1) {
+ if(phonelist.find('li').length > 1) {
$('#phones').show();
$('#contact_communication').show();
}
@@ -1493,7 +1476,25 @@ Contacts={
}
},
Contacts:{
+ contacts:{},
batchnum:50,
+ getContact:function(id) {
+ if(!this.contacts[id]) {
+ this.contacts[id] = $('#contacts li[data-id="'+id+'"]');
+ if(!this.contacts[id]) {
+ self = this;
+ $.getJSON(OC.filePath('contacts', 'ajax', 'contactdetails.php'),{'id':id},function(jsondata){
+ if(jsondata.status == 'success'){
+ self.contacts[id] = self.insertContact({data:jsondata.data});
+ }
+ else{
+ OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
+ }
+ });
+ }
+ }
+ return this.contacts[id];
+ },
drop:function(event, ui) {
var dragitem = ui.draggable, droptarget = $(this);
if(dragitem.is('li')) {
@@ -1510,21 +1511,12 @@ Contacts={
$.post(OC.filePath('contacts', 'ajax', 'movetoaddressbook.php'), { ids: dragitem.data('id'), aid: droptarget.data('id') },
function(jsondata){
if(jsondata.status == 'success'){
- // Do some inserting/removing/sorting magic
- var name = $(dragitem).find('a').html();
- var added = false;
- $(droplist).children().each(function(){
- if ($(this).text().toLowerCase() > name.toLowerCase()) {
- $(this).before(dragitem.detach()); //.fadeIn('slow');
- added = true;
- return false;
- }
- });
- if(!added) {
- $(droplist).append(dragitem.detach());
- }
dragitem.attr('data-bookid', droptarget.data('id'))
dragitem.data('bookid', droptarget.data('id'));
+ Contacts.UI.Contacts.insertContact({
+ contactlist:droplist,
+ contact:dragitem.detach()
+ });
Contacts.UI.Contacts.scrollTo(dragitem.data('id'));
} else {
OC.dialogs.alert(jsondata.data.message, t('contacts', 'Error'));
@@ -1541,13 +1533,16 @@ Contacts={
* If 'contactlist' or 'contacts' aren't defined they will be search for based in the properties in 'data'.
*/
insertContact:function(params) {
+ var id, bookid;
if(!params.contactlist) {
// FIXME: Check if contact really exists.
- var bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ id = params.data ? params.data.id : params.contact.data('id');
params.contactlist = $('#contacts ul[data-id="'+bookid+'"]');
}
if(!params.contacts) {
- var bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ bookid = params.data ? params.data.addressbookid : params.contact.data('bookid');
+ id = params.data ? params.data.id : params.contact.data('id');
params.contacts = $('#contacts ul[data-id="'+bookid+'"] li');
}
var contact = params.data
@@ -1567,8 +1562,24 @@ Contacts={
if(!added || !params.contacts) {
params.contactlist.append(contact);
}
+ //this.contacts[id] = contact;
return contact;
},
+ next:function(reverse) {
+ // TODO: Check if we're last-child/first-child and jump to next/prev address book.
+ var curlistitem = $('#contacts li[data-id="'+Contacts.UI.Card.id+'"]');
+ var newlistitem = reverse ? curlistitem.prev('li') : curlistitem.next('li');
+ if(newlistitem) {
+ curlistitem.removeClass('active');
+ Contacts.UI.Card.update({
+ cid:newlistitem.data('id'),
+ aid:newlistitem.data('bookid')
+ });
+ }
+ },
+ previous:function() {
+ this.next(true);
+ },
// Reload the contacts list.
update:function(params){
if(!params) { params = {}; }
@@ -1672,10 +1683,10 @@ Contacts={
},
scrollTo:function(id){
var item = $('#contacts li[data-id="'+id+'"]');
- console.log('scrollTo, found item '+id+'? ' + item.length);
- if(item) {
+ if(item && $.isNumeric(item.offset().top)) {
+ console.log('scrollTo ' + parseInt(item.offset().top));
$('#contacts').animate({
- scrollTop: item.offset().top-40}, 'slow','swing');
+ scrollTop: parseInt(item.offset()).top-40}, 'slow','swing');
}
}
}
@@ -1686,23 +1697,90 @@ $(document).ready(function(){
OCCategories.changed = Contacts.UI.Card.categoriesChanged;
OCCategories.app = 'contacts';
- $('#notification').click(function(){
- $('#notification').fadeOut();
+ $('#chooseaddressbook').on('click keydown', Contacts.UI.Addressbooks.overview);
+ $('#contacts_newcontact').on('click keydown', Contacts.UI.Card.editNew);
+
+ var ninjahelp = $('#ninjahelp');
+
+ ninjahelp.find('.close').on('click keydown',function() {
+ ninjahelp.hide();
});
- $('#chooseaddressbook').click(Contacts.UI.Addressbooks.overview);
- $('#chooseaddressbook').keydown(Contacts.UI.Addressbooks.overview);
+ $(document).on('keyup', function(event) {
+ console.log(event.which + ' ' + event.target.nodeName);
+ if(event.target.nodeName.toUpperCase() != 'BODY'
+ || $('#contacts li').length == 0
+ || !Contacts.UI.Card.id) {
+ return;
+ }
+ /**
+ * To add:
+ * (Shift)n/p: next/prev addressbook
+ * u (85): hide/show leftcontent
+ * f (70): add field
+ */
+ switch(event.which) {
+ case 27: // Esc
+ ninjahelp.hide();
+ break;
+ case 46:
+ if(event.shiftKey) {
+ Contacts.UI.Card.delayedDelete();
+ }
+ break;
+ case 32: // space
+ if(event.shiftKey) {
+ Contacts.UI.Contacts.previous();
+ break;
+ }
+ case 40: // down
+ case 75: // k
+ Contacts.UI.Contacts.next();
+ break;
+ case 65: // a
+ if(event.shiftKey) {
+ // add addressbook
+ Contacts.UI.notImplemented();
+ break;
+ }
+ Contacts.UI.Card.editNew();
+ break;
+ case 38: // up
+ case 74: // j
+ Contacts.UI.Contacts.previous();
+ break;
+ case 78: // n
+ // next addressbook
+ Contacts.UI.notImplemented();
+ break;
+ case 13: // Enter
+ case 79: // o
+ var aid = $('#contacts h3.active').first().data('id');
+ if(aid) {
+ $('#contacts ul[data-id="'+aid+'"]').slideToggle(300);
+ }
+ break;
+ case 80: // p
+ // prev addressbook
+ Contacts.UI.notImplemented();
+ break;
+ case 82: // r
+ Contacts.UI.Contacts.update({cid:Contacts.UI.Card.id});
+ break;
+ case 191: // ?
+ ninjahelp.toggle('fast');
+ break;
+ }
- $('#contacts_newcontact').click(Contacts.UI.Card.editNew);
- $('#contacts_newcontact').keydown(Contacts.UI.Card.editNew);
+ });
- // Load a contact.
+ // Load a contact.
$('.contacts').keydown(function(event) {
if(event.which == 13 || event.which == 32) {
$('.contacts').click();
}
});
- $(document).on('click', '.contacts', function(event){
+ $(document).on('click', '#contacts', function(event){
var $tgt = $(event.target);
if ($tgt.is('li') || $tgt.is('a')) {
var item = $tgt.is('li')?$($tgt):($tgt).parent();
@@ -1931,14 +2009,15 @@ $(document).ready(function(){
$('#selectaddressbook_dialog').dialog('moveToTop');
} else {
$('#dialog_holder').html(jsondata.data.page).ready(function($) {
- $('#selectaddressbook_dialog').dialog({
+ var select_dlg = $('#selectaddressbook_dialog');
+ select_dlg.dialog({
modal: true, height: 'auto', width: 'auto',
buttons: {
'Ok':function() {
- aid = $('#selectaddressbook_dialog').find('input:checked').val();
+ aid = select_dlg.find('input:checked').val();
if(aid == 'new') {
- var displayname = $('#selectaddressbook_dialog').find('input.name').val();
- var description = $('#selectaddressbook_dialog').find('input.desc').val();
+ var displayname = select_dlg.find('input.name').val();
+ var description = select_dlg.find('input.desc').val();
if(!displayname.trim()) {
OC.dialogs.alert(t('contacts', 'The address book name cannot be empty.'), t('contacts', 'Error'));
return false;
diff --git a/apps/contacts/js/loader.js b/apps/contacts/js/loader.js
index 577ad103064..5bca0ab7237 100644
--- a/apps/contacts/js/loader.js
+++ b/apps/contacts/js/loader.js
@@ -78,9 +78,9 @@ Contacts_Import={
}
$(document).ready(function(){
if(typeof FileActions !== 'undefined'){
- FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/vcard','importaddressbook');
- FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
+ FileActions.register('text/x-vcard','importaddressbook', '', Contacts_Import.importdialog);
FileActions.setDefault('text/x-vcard','importaddressbook');
};
}); \ No newline at end of file
diff --git a/apps/contacts/l10n/it.php b/apps/contacts/l10n/it.php
index 2a5478e6c4b..820104b7774 100644
--- a/apps/contacts/l10n/it.php
+++ b/apps/contacts/l10n/it.php
@@ -1,10 +1,13 @@
<?php $TRANSLATIONS = array(
"Error (de)activating addressbook." => "Errore nel (dis)attivare la rubrica.",
"There was an error adding the contact." => "Si è verificato un errore nell'aggiunta del contatto.",
+"element name is not set." => "il nome dell'elemento non è impostato.",
+"id is not set." => "ID non impostato.",
+"Could not parse contact: " => "Impossibile elaborare il contatto: ",
"Cannot add empty property." => "Impossibile aggiungere una proprietà vuota.",
"At least one of the address fields has to be filled out." => "Deve essere riempito almeno un indirizzo.",
"Trying to add duplicate property: " => "P",
-"Error adding contact property." => "Errore durante l'aggiunta della proprietà del contatto.",
+"Error adding contact property: " => "Errore durante l'aggiunta della proprietà del contatto: ",
"No ID provided" => "Nessun ID fornito",
"Error setting checksum." => "Errore di impostazione del codice di controllo.",
"No categories selected for deletion." => "Nessuna categoria selezionata per l'eliminazione.",
@@ -12,22 +15,23 @@
"No contacts found." => "Nessun contatto trovato.",
"Missing ID" => "ID mancante",
"Error parsing VCard for ID: \"" => "Errore in fase di elaborazione del file VCard per l'ID: \"",
-"Cannot add addressbook with an empty name." => "Impossibile aggiungere una rubrica senza nome.",
-"Error adding addressbook." => "Errore durante l'aggiunta della rubrica.",
-"Error activating addressbook." => "Errore durante l'attivazione della rubrica.",
"No contact ID was submitted." => "Nessun ID di contatto inviato.",
"Error reading contact photo." => "Errore di lettura della foto del contatto.",
"Error saving temporary file." => "Errore di salvataggio del file temporaneo.",
"The loading photo is not valid." => "La foto caricata non è valida.",
-"id is not set." => "ID non impostato.",
"Information about vCard is incorrect. Please reload the page." => "Informazioni sulla vCard non corrette. Ricarica la pagina.",
"Error deleting contact property." => "Errore durante l'eliminazione della proprietà del contatto.",
"Contact ID is missing." => "Manca l'ID del contatto.",
-"Missing contact id." => "ID di contatto mancante.",
"No photo path was submitted." => "Non è stato inviato alcun percorso a una foto.",
"File doesn't exist:" => "Il file non esiste:",
"Error loading image." => "Errore di caricamento immagine.",
-"element name is not set." => "il nome dell'elemento non è impostato.",
+"Error getting contact object." => "Errore di recupero dell'oggetto contatto.",
+"Error getting PHOTO property." => "Errore di recupero della proprietà FOTO.",
+"Error saving contact." => "Errore di salvataggio del contatto.",
+"Error resizing image" => "Errore di ridimensionamento dell'immagine",
+"Error cropping image" => "Errore di ritaglio dell'immagine",
+"Error creating temporary image" => "Errore durante la creazione dell'immagine temporanea",
+"Error finding image: " => "Errore durante la ricerca dell'immagine: ",
"checksum is not set." => "il codice di controllo non è impostato.",
"Information about vCard is incorrect. Please reload the page: " => "Le informazioni della vCard non sono corrette. Ricarica la pagina: ",
"Something went FUBAR. " => "Qualcosa è andato storto. ",
@@ -41,8 +45,27 @@
"The uploaded file was only partially uploaded" => "Il file è stato inviato solo parzialmente",
"No file was uploaded" => "Nessun file è stato inviato",
"Missing a temporary folder" => "Manca una cartella temporanea",
+"Couldn't save temporary image: " => "Impossibile salvare l'immagine temporanea: ",
+"Couldn't load temporary image: " => "Impossibile caricare l'immagine temporanea: ",
+"No file was uploaded. Unknown error" => "Nessun file è stato inviato. Errore sconosciuto",
"Contacts" => "Contatti",
-"Drop a VCF file to import contacts." => "Rilascia un file VCF per importare i contatti.",
+"Sorry, this functionality has not been implemented yet" => "Siamo spiacenti, questa funzionalità non è stata ancora implementata",
+"Not implemented" => "Non implementata",
+"Couldn't get a valid address." => "Impossibile ottenere un indirizzo valido.",
+"Error" => "Errore",
+"Contact" => "Contatto",
+"New" => "Nuovo",
+"New Contact" => "Nuovo contatto",
+"This property has to be non-empty." => "Questa proprietà non può essere vuota.",
+"Couldn't serialize elements." => "Impossibile serializzare gli elementi.",
+"'deleteProperty' called without type argument. Please report at bugs.owncloud.org" => "'deleteProperty' invocata senza l'argomento di tipo. Segnalalo a bugs.owncloud.org",
+"Edit name" => "Modifica il nome",
+"No files selected for upload." => "Nessun file selezionato per l'invio",
+"The file you are trying to upload exceed the maximum size for file uploads on this server." => "Il file che stai cercando di inviare supera la dimensione massima per l'invio dei file su questo server.",
+"Select type" => "Seleziona il tipo",
+"Result: " => "Risultato: ",
+" imported, " => " importato, ",
+" failed." => " non riuscito.",
"Addressbook not found." => "Rubrica non trovata.",
"This is not your addressbook." => "Questa non è la tua rubrica.",
"Contact could not be found." => "Il contatto non può essere trovato.",
@@ -60,25 +83,54 @@
"Video" => "Video",
"Pager" => "Cercapersone",
"Internet" => "Internet",
+"Birthday" => "Compleanno",
+"Business" => "Lavoro",
+"Call" => "Chiama",
+"Clients" => "Client",
+"Deliverer" => "Corriere",
+"Holidays" => "Festività",
+"Ideas" => "Idee",
+"Journey" => "Viaggio",
+"Jubilee" => "Anniversario",
+"Meeting" => "Riunione",
+"Other" => "Altro",
+"Personal" => "Personale",
+"Projects" => "Progetti",
+"Questions" => "Domande",
"{name}'s Birthday" => "Data di nascita di {name}",
-"Contact" => "Contatto",
"Add Contact" => "Aggiungi contatto",
+"Import" => "Importa",
"Addressbooks" => "Rubriche",
+"Close" => "Chiudi",
+"Keyboard shortcuts" => "Scorciatoie da tastiera",
+"Navigation" => "Navigazione",
+"Next contact in list" => "Contatto successivo in elenco",
+"Previous contact in list" => "Contatto precedente in elenco",
+"Expand/collapse current addressbook" => "Espandi/Contrai la rubrica corrente",
+"Next/previous addressbook" => "Rubrica successiva/precedente",
+"Actions" => "Azioni",
+"Refresh contacts list" => "Aggiorna l'elenco dei contatti",
+"Add new contact" => "Aggiungi un nuovo contatto",
+"Add new addressbook" => "Aggiungi una nuova rubrica",
+"Delete current contact" => "Elimina il contatto corrente",
"Configure Address Books" => "Configura rubrica",
"New Address Book" => "Nuova rubrica",
-"Import from VCF" => "Importa da VCF",
"CardDav Link" => "Link CardDav",
"Download" => "Scarica",
"Edit" => "Modifica",
"Delete" => "Elimina",
-"Download contact" => "Scarica contatto",
-"Delete contact" => "Elimina contatto",
"Drop photo to upload" => "Rilascia una foto da inviare",
+"Delete current photo" => "Elimina la foto corrente",
+"Edit current photo" => "Modifica la foto corrente",
+"Upload new photo" => "Invia una nuova foto",
+"Select photo from ownCloud" => "Seleziona la foto da ownCloud",
"Format custom, Short name, Full name, Reverse or Reverse with comma" => "Formato personalizzato, nome breve, nome completo, invertito o invertito con virgola",
"Edit name details" => "Modifica dettagli del nome",
"Nickname" => "Pseudonimo",
"Enter nickname" => "Inserisci pseudonimo",
-"Birthday" => "Compleanno",
+"Web site" => "Sito web",
+"http://www.somesite.com" => "http://www.somesite.com",
+"Go to web site" => "Vai al sito web",
"dd-mm-yyyy" => "gg-mm-aaaa",
"Groups" => "Gruppi",
"Separate groups with commas" => "Separa i gruppi con virgole",
@@ -94,24 +146,24 @@
"Edit address details" => "Modifica dettagli dell'indirizzo",
"Add notes here." => "Aggiungi qui le note.",
"Add field" => "Aggiungi campo",
-"Profile picture" => "Immagine del profilo",
"Phone" => "Telefono",
"Note" => "Nota",
-"Delete current photo" => "Elimina la foto corrente",
-"Edit current photo" => "Modifica la foto corrente",
-"Upload new photo" => "Invia una nuova foto",
-"Select photo from ownCloud" => "Seleziona la foto da ownCloud",
+"Download contact" => "Scarica contatto",
+"Delete contact" => "Elimina contatto",
+"The temporary image has been removed from cache." => "L'immagine temporanea è stata rimossa dalla cache.",
"Edit address" => "Modifica indirizzo",
"Type" => "Tipo",
"PO Box" => "Casella postale",
+"Street address" => "Indirizzo",
+"Street and number" => "Via e numero",
"Extended" => "Esteso",
-"Street" => "Via",
+"Apartment number etc." => "Numero appartamento ecc.",
"City" => "Città",
"Region" => "Regione",
+"E.g. state or province" => "Ad es. stato o provincia",
"Zipcode" => "CAP",
+"Postal code" => "CAP",
"Country" => "Stato",
-"Edit categories" => "Modifica categorie",
-"Add" => "Aggiungi",
"Addressbook" => "Rubrica",
"Hon. prefixes" => "Prefissi onorifici",
"Miss" => "Sig.na",
@@ -143,15 +195,16 @@
"Please choose the addressbook" => "Scegli la rubrica",
"create a new addressbook" => "crea una nuova rubrica",
"Name of new addressbook" => "Nome della nuova rubrica",
-"Import" => "Importa",
"Importing contacts" => "Importazione contatti",
-"Select address book to import to:" => "Seleziona la rubrica di destinazione:",
-"Select from HD" => "Seleziona da disco",
"You have no contacts in your addressbook." => "Non hai contatti nella rubrica.",
"Add contact" => "Aggiungi contatto",
"Configure addressbooks" => "Configura rubriche",
+"Select Address Books" => "Seleziona rubriche",
+"Enter name" => "Inserisci il nome",
+"Enter description" => "Inserisci una descrizione",
"CardDAV syncing addresses" => "Indirizzi di sincronizzazione CardDAV",
"more info" => "altre informazioni",
"Primary address (Kontact et al)" => "Indirizzo principale (Kontact e altri)",
-"iOS/OS X" => "iOS/OS X"
+"iOS/OS X" => "iOS/OS X",
+"Read only vCard directory link(s)" => "Collegamento(i) cartella vCard sola lettura"
);
diff --git a/apps/contacts/l10n/vi.php b/apps/contacts/l10n/vi.php
new file mode 100644
index 00000000000..5713ede7b00
--- /dev/null
+++ b/apps/contacts/l10n/vi.php
@@ -0,0 +1,48 @@
+<?php $TRANSLATIONS = array(
+"element name is not set." => "tên phần tử không được thiết lập.",
+"id is not set." => "id không được thiết lập.",
+"No ID provided" => "Không có ID được cung cấp",
+"No address books found." => "Không tìm thấy sổ địa chỉ.",
+"No contacts found." => "Không tìm thấy danh sách",
+"Missing ID" => "Missing ID",
+"Error reading contact photo." => "Lỗi đọc liên lạc hình ảnh.",
+"The loading photo is not valid." => "Các hình ảnh tải không hợp lệ.",
+"File doesn't exist:" => "Tập tin không tồn tại",
+"Error loading image." => "Lỗi khi tải hình ảnh.",
+"Error uploading contacts to storage." => "Lỗi tải lên danh sách địa chỉ để lưu trữ.",
+"There is no error, the file uploaded with success" => "Không có lỗi, các tập tin tải lên thành công",
+"Contacts" => "Liên lạc",
+"Contact" => "Danh sách",
+"Address" => "Địa chỉ",
+"Telephone" => "Điện thoại bàn",
+"Email" => "Email",
+"Organization" => "Tổ chức",
+"Work" => "Công việc",
+"Home" => "Nhà",
+"Mobile" => "Di động",
+"Fax" => "Fax",
+"Video" => "Video",
+"Pager" => "số trang",
+"Birthday" => "Ngày sinh nhật",
+"Add Contact" => "Thêm liên lạc",
+"Addressbooks" => "Sổ địa chỉ",
+"CardDav Link" => "CardDav Link",
+"Download" => "Tải về",
+"Edit" => "Sửa",
+"Delete" => "Xóa",
+"Phone" => "Điện thoại",
+"Delete contact" => "Xóa liên lạc",
+"PO Box" => "Hòm thư bưu điện",
+"City" => "Thành phố",
+"Region" => "Vùng/miền",
+"Zipcode" => "Mã bưu điện",
+"Country" => "Quốc gia",
+"Addressbook" => "Sổ địa chỉ",
+"New Addressbook" => "Sổ địa chỉ mới",
+"Edit Addressbook" => "Sửa sổ địa chỉ",
+"Displayname" => "Hiển thị tên",
+"Active" => "Kích hoạt",
+"Save" => "Lưu",
+"Submit" => "Submit",
+"Cancel" => "Hủy"
+);
diff --git a/apps/contacts/templates/index.php b/apps/contacts/templates/index.php
index 1bc4a195534..b2dde12684c 100644
--- a/apps/contacts/templates/index.php
+++ b/apps/contacts/templates/index.php
@@ -32,6 +32,38 @@
echo $this->inc('part.no_contacts');
}
?>
+ <div class="hidden" id="ninjahelp">
+ <a class="close" tabindex="0" role="button">
+ <img class="svg" src="core/img/actions/delete.svg" alt="<?php echo $l->t('Close'); ?>" />
+ </a>
+ <h2><?php echo $l->t('Keyboard shortcuts'); ?></h2>
+ <div class="help-section">
+ <h3><?php echo $l->t('Navigation'); ?></h3>
+ <dl>
+ <dt>j/Down/Space</dt>
+ <dd><?php echo $l->t('Next contact in list'); ?></dd>
+ <dt>k/Up/Shift-Space</dt>
+ <dd><?php echo $l->t('Previous contact in list'); ?></dd>
+ <dt>o/Enter</dt>
+ <dd><?php echo $l->t('Expand/collapse current addressbook'); ?></dd>
+ <dt>n/p</dt>
+ <dd><?php echo $l->t('Next/previous addressbook'); ?></dd>
+ </dl>
+ </div>
+ <div class="help-section">
+ <h3><?php echo $l->t('Actions'); ?></h3>
+ <dl>
+ <dt>r</dt>
+ <dd><?php echo $l->t('Refresh contacts list'); ?></dd>
+ <dt>a</dt>
+ <dd><?php echo $l->t('Add new contact'); ?></dd>
+ <dt>Shift-a</dt>
+ <dd><?php echo $l->t('Add new addressbook'); ?></dd>
+ <dt>Shift-Delete</dt>
+ <dd><?php echo $l->t('Delete current contact'); ?></dd>
+ </dl>
+ </div>
+ </div>
</div>
<!-- Dialogs -->
<div id="dialog_holder"></div>
diff --git a/apps/files/ajax/newfile.php b/apps/files/ajax/newfile.php
index 7236deb65c9..cc9208ad08f 100644
--- a/apps/files/ajax/newfile.php
+++ b/apps/files/ajax/newfile.php
@@ -1,16 +1,25 @@
<?php
// Init owncloud
+global $eventSource;
+if(!OC_User::isLoggedIn()){
+ exit;
+}
-OCP\JSON::checkLoggedIn();
-OCP\JSON::callCheck();
+session_write_close();
// Get the params
-$dir = isset( $_POST['dir'] ) ? stripslashes($_POST['dir']) : '';
-$filename = isset( $_POST['filename'] ) ? stripslashes($_POST['filename']) : '';
-$content = isset( $_POST['content'] ) ? $_POST['content'] : '';
-$source = isset( $_POST['source'] ) ? stripslashes($_POST['source']) : '';
+$dir = isset( $_REQUEST['dir'] ) ? stripslashes($_REQUEST['dir']) : '';
+$filename = isset( $_REQUEST['filename'] ) ? stripslashes($_REQUEST['filename']) : '';
+$content = isset( $_REQUEST['content'] ) ? $_REQUEST['content'] : '';
+$source = isset( $_REQUEST['source'] ) ? stripslashes($_REQUEST['source']) : '';
+
+if($source){
+ $eventSource=new OC_EventSource();
+}else{
+ OC_JSON::callCheck();
+}
if($filename == '') {
OCP\JSON::error(array("data" => array( "message" => "Empty Filename" )));
@@ -21,22 +30,49 @@ if(strpos($filename,'/')!==false){
exit();
}
+function progress($notification_code, $severity, $message, $message_code, $bytes_transferred, $bytes_max){
+ static $filesize = 0;
+ static $lastsize = 0;
+ global $eventSource;
+
+ switch($notification_code) {
+ case STREAM_NOTIFY_FILE_SIZE_IS:
+ $filesize = $bytes_max;
+ break;
+
+ case STREAM_NOTIFY_PROGRESS:
+ if ($bytes_transferred > 0) {
+ if (!isset($filesize)) {
+ } else {
+ $progress = (int)(($bytes_transferred/$filesize)*100);
+ if($progress>$lastsize){//limit the number or messages send
+ $eventSource->send('progress',$progress);
+ }
+ $lastsize=$progress;
+ }
+ }
+ break;
+ }
+}
+
if($source){
if(substr($source,0,8)!='https://' and substr($source,0,7)!='http://'){
OCP\JSON::error(array("data" => array( "message" => "Not a valid source" )));
exit();
}
- $sourceStream=fopen($source,'rb');
+
+ $ctx = stream_context_create(null, array('notification' =>'progress'));
+ $sourceStream=fopen($source,'rb', false, $ctx);
$target=$dir.'/'.$filename;
$result=OC_Filesystem::file_put_contents($target,$sourceStream);
if($result){
$mime=OC_Filesystem::getMimetype($target);
- OCP\JSON::success(array("data" => array('mime'=>$mime)));
- exit();
+ $eventSource->send('success',$mime);
}else{
- OCP\JSON::error(array("data" => array( "message" => "Error while downloading ".$source. ' to '.$target )));
- exit();
+ $eventSource->send('error',"Error while downloading ".$source. ' to '.$target);
}
+ $eventSource->close();
+ exit();
}else{
if($content){
if(OC_Filesystem::file_put_contents($dir.'/'.$filename,$content)){
diff --git a/apps/files/ajax/scan.php b/apps/files/ajax/scan.php
index 6fcf97688c2..eef38858516 100644
--- a/apps/files/ajax/scan.php
+++ b/apps/files/ajax/scan.php
@@ -16,6 +16,11 @@ session_write_close();
if($force or !OC_FileCache::inCache('')){
if(!$checkOnly){
OCP\DB::beginTransaction();
+
+ if(OC_Cache::isFast()){
+ OC_Cache::clear('fileid/'); //make sure the old fileid's don't mess things up
+ }
+
OC_FileCache::scan($dir,$eventSource);
OC_FileCache::clean();
OCP\DB::commit();
diff --git a/apps/files/appinfo/update.php b/apps/files/appinfo/update.php
index f9953ba4de5..5514aed197f 100644
--- a/apps/files/appinfo/update.php
+++ b/apps/files/appinfo/update.php
@@ -1,5 +1,16 @@
<?php
+// fix webdav properties, remove namespace information between curly bracket (update from OC4 to OC5)
+$installedVersion=OCP\Config::getAppValue('files', 'installed_version');
+if (version_compare($installedVersion, '1.1.4', '<')) {
+ $query = OC_DB::prepare( "SELECT propertyname, propertypath, userid FROM `*PREFIX*properties`" );
+ $result = $query->execute();
+ while( $row = $result->fetchRow()){
+ $query = OC_DB::prepare( 'UPDATE *PREFIX*properties SET propertyname = ? WHERE userid = ? AND propertypath = ?' );
+ $query->execute( array( preg_replace("/^{.*}/", "", $row["propertyname"]),$row["userid"], $row["propertypath"] ));
+ }
+}
+
//update from OC 3
//try to remove remaining files.
diff --git a/apps/files/appinfo/version b/apps/files/appinfo/version
index 9c1218c201f..1b87bcd0b09 100644
--- a/apps/files/appinfo/version
+++ b/apps/files/appinfo/version
@@ -1 +1 @@
-1.1.3 \ No newline at end of file
+1.1.4 \ No newline at end of file
diff --git a/apps/files/js/files.js b/apps/files/js/files.js
index 86c5185bf72..a4e2361feeb 100644
--- a/apps/files/js/files.js
+++ b/apps/files/js/files.js
@@ -497,23 +497,27 @@ $(document).ready(function() {
localName=(localName.match(/:\/\/(.[^/]+)/)[1]).replace('www.','');
}
localName = getUniqueName(localName);
- $.post(
- OC.filePath('files','ajax','newfile.php'),
- {dir:$('#dir').val(),source:name,filename:localName},
- function(result){
- if(result.status == 'success'){
- var date=new Date();
- FileList.addFile(localName,0,date);
- var tr=$('tr').filterAttr('data-file',localName);
- tr.data('mime',result.data.mime);
- getMimeIcon(result.data.mime,function(path){
- tr.find('td.filename').attr('style','background-image:url('+path+')');
- });
- }else{
+ $('#uploadprogressbar').progressbar({value:0});
+ $('#uploadprogressbar').fadeIn();
- }
- }
- );
+ var eventSource=new OC.EventSource(OC.filePath('files','ajax','newfile.php'),{dir:$('#dir').val(),source:name,filename:localName});
+ eventSource.listen('progress',function(progress){
+ $('#uploadprogressbar').progressbar('value',progress);
+ });
+ eventSource.listen('success',function(mime){
+ $('#uploadprogressbar').fadeOut();
+ var date=new Date();
+ FileList.addFile(localName,0,date);
+ var tr=$('tr').filterAttr('data-file',localName);
+ tr.data('mime',mime);
+ getMimeIcon(mime,function(path){
+ tr.find('td.filename').attr('style','background-image:url('+path+')');
+ });
+ });
+ eventSource.listen('error',function(error){
+ $('#uploadprogressbar').fadeOut();
+ alert(error);
+ });
break;
}
var li=$(this).parent();
diff --git a/apps/files/l10n/es.php b/apps/files/l10n/es.php
index 67bfb4702e8..506218815bb 100644
--- a/apps/files/l10n/es.php
+++ b/apps/files/l10n/es.php
@@ -7,8 +7,21 @@
"Missing a temporary folder" => "Falta un directorio temporal",
"Failed to write to disk" => "La escritura en disco ha fallado",
"Files" => "Archivos",
+"Unshare" => "No compartir",
+"Delete" => "Eliminado",
+"undo deletion" => "deshacer la eliminación",
+"generating ZIP-file, it may take some time." => "generando un fichero ZIP, puede llevar un tiempo.",
+"Unable to upload your file as it is a directory or has 0 bytes" => "No ha sido posible subir tu archivo porque es un directorio o tiene 0 bytes",
+"Upload Error" => "Error al subir el archivo",
+"Pending" => "Pendiente",
+"Upload cancelled." => "Subida cancelada.",
+"Invalid name, '/' is not allowed." => "Nombre no válido, '/' no está permitido.",
"Size" => "Tamaño",
"Modified" => "Modificado",
+"folder" => "carpeta",
+"folders" => "carpetas",
+"file" => "archivo",
+"files" => "archivos",
"File handling" => "Tratamiento de archivos",
"Maximum upload size" => "Tamaño máximo de subida",
"max. possible: " => "máx. posible:",
@@ -26,7 +39,6 @@
"Name" => "Nombre",
"Share" => "Compartir",
"Download" => "Descargar",
-"Delete" => "Eliminado",
"Upload too large" => "El archivo es demasiado grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "Los archivos que estás intentando subir sobrepasan el tamaño máximo permitido por este servidor.",
"Files are being scanned, please wait." => "Se están escaneando los archivos, por favor espere.",
diff --git a/apps/files/l10n/it.php b/apps/files/l10n/it.php
index 82871826c18..0bf113eba1b 100644
--- a/apps/files/l10n/it.php
+++ b/apps/files/l10n/it.php
@@ -7,8 +7,21 @@
"Missing a temporary folder" => "Cartella temporanea mancante",
"Failed to write to disk" => "Scrittura su disco non riuscita",
"Files" => "File",
+"Unshare" => "Rimuovi condivisione",
+"Delete" => "Elimina",
+"undo deletion" => "annulla l'eliminazione",
+"generating ZIP-file, it may take some time." => "creazione file ZIP, potrebbe richiedere del tempo.",
+"Unable to upload your file as it is a directory or has 0 bytes" => "Impossibile inviare il file poiché è una cartella o ha dimensione 0 byte",
+"Upload Error" => "Errore di invio",
+"Pending" => "In corso",
+"Upload cancelled." => "Invio annullato",
+"Invalid name, '/' is not allowed." => "Nome non valido",
"Size" => "Dimensione",
"Modified" => "Modificato",
+"folder" => "cartella",
+"folders" => "cartelle",
+"file" => "file",
+"files" => "file",
"File handling" => "Gestione file",
"Maximum upload size" => "Dimensione massima upload",
"max. possible: " => "numero mass.: ",
@@ -26,7 +39,6 @@
"Name" => "Nome",
"Share" => "Condividi",
"Download" => "Scarica",
-"Delete" => "Elimina",
"Upload too large" => "Il file caricato è troppo grande",
"The files you are trying to upload exceed the maximum size for file uploads on this server." => "I file che stai provando a caricare superano la dimensione massima consentita su questo server.",
"Files are being scanned, please wait." => "Scansione dei file in corso, attendi",
diff --git a/apps/files/l10n/vi.php b/apps/files/l10n/vi.php
new file mode 100644
index 00000000000..c2284d5feb9
--- /dev/null
+++ b/apps/files/l10n/vi.php
@@ -0,0 +1,31 @@
+<?php $TRANSLATIONS = array(
+"Files" => "Tập tin",
+"Delete" => "Xóa",
+"Upload Error" => "Tải lên lỗi",
+"Pending" => "Chờ",
+"Upload cancelled." => "Hủy tải lên",
+"Invalid name, '/' is not allowed." => "Tên không hợp lệ ,không được phép dùng '/'",
+"Size" => "Kích cỡ",
+"Modified" => "Thay đổi",
+"folder" => "folder",
+"folders" => "folders",
+"file" => "file",
+"files" => "files",
+"File handling" => "Xử lý tập tin",
+"Maximum upload size" => "Kích thước tối đa ",
+"Enable ZIP-download" => "Cho phép ZIP-download",
+"0 is unlimited" => "0 là không giới hạn",
+"Maximum input size for ZIP files" => "Kích thước tối đa cho các tập tin ZIP",
+"New" => "Mới",
+"Text file" => "Tập tin văn bản",
+"Folder" => "Folder",
+"From url" => "Từ url",
+"Upload" => "Tải lên",
+"Cancel upload" => "Hủy upload",
+"Nothing in here. Upload something!" => "Không có gì ở đây .Hãy tải lên một cái gì đó !",
+"Name" => "Tên",
+"Share" => "Chia sẻ",
+"Download" => "Tải xuống",
+"Upload too large" => "File tải lên quá lớn",
+"Files are being scanned, please wait." => "Tập tin đang được quét ,vui lòng chờ."
+);
diff --git a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js
index a1db7b6198c..e5493cd9393 100644
--- a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js
+++ b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.js
@@ -124,9 +124,7 @@
} else if (href.indexOf("#") === 0) {
type = 'inline';
- } else {
- type = 'ajax';
- }
+ }
}
if (!type) {
diff --git a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js
index e5ee2ae3595..260f2c2d466 100644
--- a/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js
+++ b/apps/files_imageviewer/js/jquery.fancybox-1.3.4.pack.js
@@ -1 +1 @@
-(function(B){var L,T,Q,M,d,m,J,A,O,z,C=0,H={},j=[],e=0,G={},y=[],f=null,o=new Image(),i=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,k=/[^\.]\.(swf)\s*$/i,p,N=1,h=0,t="",b,c,P=false,s=B.extend(B("<div/>")[0],{prop:0}),S=B.browser.msie&&B.browser.version<7&&!window.XMLHttpRequest,r=function(){T.hide();o.onerror=o.onload=null;if(f){f.abort()}L.empty()},x=function(){if(false===H.onError(j,C,H)){T.hide();P=false;return}H.titleShow=false;H.width="auto";H.height="auto";L.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');n()},w=function(){var Z=j[C],W,Y,ab,aa,V,X;r();H=B.extend({},B.fn.fancybox.defaults,(typeof B(Z).data("fancybox")=="undefined"?H:B(Z).data("fancybox")));X=H.onStart(j,C,H);if(X===false){P=false;return}else{if(typeof X=="object"){H=B.extend(H,X)}}ab=H.title||(Z.nodeName?B(Z).attr("title"):Z.title)||"";if(Z.nodeName&&!H.orig){H.orig=B(Z).children("img:first").length?B(Z).children("img:first"):B(Z)}if(ab===""&&H.orig&&H.titleFromAlt){ab=H.orig.attr("alt")}ab=ab.replace(/</,"&lt;").replace(/>/,"&gt;");W=H.href||(Z.nodeName?B(Z).attr("href"):Z.href)||null;if((/^(?:javascript)/i).test(W)||W=="#"){W=null}if(H.type){Y=H.type;if(!W){W=H.content}}else{if(H.content){Y="html"}else{if(W){if(W.match(i)){Y="image"}else{if(W.match(k)){Y="swf"}else{if(B(Z).hasClass("iframe")){Y="iframe"}else{if(W.indexOf("#")===0){Y="inline"}else{Y="ajax"}}}}}}}if(!Y){x();return}if(Y=="inline"){Z=W.substr(W.indexOf("#"));Y=B(Z).length>0?"inline":"ajax"}H.type=Y;H.href=W;H.title=ab;if(H.autoDimensions){if(H.type=="html"||H.type=="inline"||H.type=="ajax"){H.width="auto";H.height="auto"}else{H.autoDimensions=false}}if(H.modal){H.overlayShow=true;H.hideOnOverlayClick=false;H.hideOnContentClick=false;H.enableEscapeButton=false;H.showCloseButton=false}H.padding=parseInt(H.padding,10);H.margin=parseInt(H.margin,10);L.css("padding",(H.padding+H.margin));B(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){B(this).replaceWith(m.children())});switch(Y){case"html":L.html(H.content);n();break;case"inline":if(B(Z).parent().is("#fancybox-content")===true){P=false;return}B('<div class="fancybox-inline-tmp" />').hide().insertBefore(B(Z)).bind("fancybox-cleanup",function(){B(this).replaceWith(m.children())}).bind("fancybox-cancel",function(){B(this).replaceWith(L.children())});B(Z).appendTo(L);n();break;case"image":P=false;B.fancybox.showActivity();o=new Image();o.onerror=function(){x()};o.onload=function(){P=true;o.onerror=o.onload=null;F()};o.src=W;break;case"swf":H.scrolling="no";aa='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+H.width+'" height="'+H.height+'"><param name="movie" value="'+W+'"></param>';V="";B.each(H.swf,function(ac,ad){aa+='<param name="'+ac+'" value="'+ad+'"></param>';V+=" "+ac+'="'+ad+'"'});aa+='<embed src="'+W+'" type="application/x-shockwave-flash" width="'+H.width+'" height="'+H.height+'"'+V+"></embed></object>";L.html(aa);n();break;case"ajax":P=false;B.fancybox.showActivity();H.ajax.win=H.ajax.success;f=B.ajax(B.extend({},H.ajax,{url:W,data:H.ajax.data||{},error:function(ac,ae,ad){if(ac.status>0){x()}},success:function(ad,af,ac){var ae=typeof ac=="object"?ac:f;if(ae.status==200){if(typeof H.ajax.win=="function"){X=H.ajax.win(W,ad,af,ac);if(X===false){T.hide();return}else{if(typeof X=="string"||typeof X=="object"){ad=X}}}L.html(ad);n()}}}));break;case"iframe":E();break}},n=function(){var V=H.width,W=H.height;if(V.toString().indexOf("%")>-1){V=parseInt((B(window).width()-(H.margin*2))*parseFloat(V)/100,10)+"px"}else{V=V=="auto"?"auto":V+"px"}if(W.toString().indexOf("%")>-1){W=parseInt((B(window).height()-(H.margin*2))*parseFloat(W)/100,10)+"px"}else{W=W=="auto"?"auto":W+"px"}L.wrapInner('<div style="width:'+V+";height:"+W+";overflow: "+(H.scrolling=="auto"?"auto":(H.scrolling=="yes"?"scroll":"hidden"))+';position:relative;"></div>');H.width=L.width();H.height=L.height();E()},F=function(){H.width=o.width;H.height=o.height;B("<img />").attr({id:"fancybox-img",src:o.src,alt:H.title}).appendTo(L);E()},E=function(){var W,V;T.hide();if(M.is(":visible")&&false===G.onCleanup(y,e,G)){B.event.trigger("fancybox-cancel");P=false;return}P=true;B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");if(M.is(":visible")&&G.titlePosition!=="outside"){M.css("height",M.height())}y=j;e=C;G=H;if(G.overlayShow){Q.css({"background-color":G.overlayColor,opacity:G.overlayOpacity,cursor:G.hideOnOverlayClick?"pointer":"auto",height:B(document).height()});if(!Q.is(":visible")){if(S){B("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"})}Q.show()}}else{Q.hide()}c=R();l();if(M.is(":visible")){B(J.add(O).add(z)).hide();W=M.position(),b={top:W.top,left:W.left,width:M.width(),height:M.height()};V=(b.width==c.width&&b.height==c.height);m.fadeTo(G.changeFade,0.3,function(){var X=function(){m.html(L.contents()).fadeTo(G.changeFade,1,v)};B.event.trigger("fancybox-change");m.empty().removeAttr("filter").css({"border-width":G.padding,width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2});if(V){X()}else{s.prop=0;B(s).animate({prop:1},{duration:G.changeSpeed,easing:G.easingChange,step:U,complete:X})}});return}M.removeAttr("style");m.css("border-width",G.padding);if(G.transitionIn=="elastic"){b=I();m.html(L.contents());M.show();if(G.opacity){c.opacity=0}s.prop=0;B(s).animate({prop:1},{duration:G.speedIn,easing:G.easingIn,step:U,complete:v});return}if(G.titlePosition=="inside"&&h>0){A.show()}m.css({width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2}).html(L.contents());M.css(c).fadeIn(G.transitionIn=="none"?0:G.speedIn,v)},D=function(V){if(V&&V.length){if(G.titlePosition=="float"){return'<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">'+V+'</td><td id="fancybox-title-float-right"></td></tr></table>'}return'<div id="fancybox-title-'+G.titlePosition+'">'+V+"</div>"}return false},l=function(){t=G.title||"";h=0;A.empty().removeAttr("style").removeClass();if(G.titleShow===false){A.hide();return}t=B.isFunction(G.titleFormat)?G.titleFormat(t,y,e,G):D(t);if(!t||t===""){A.hide();return}A.addClass("fancybox-title-"+G.titlePosition).html(t).appendTo("body").show();switch(G.titlePosition){case"inside":A.css({width:c.width-(G.padding*2),marginLeft:G.padding,marginRight:G.padding});h=A.outerHeight(true);A.appendTo(d);c.height+=h;break;case"over":A.css({marginLeft:G.padding,width:c.width-(G.padding*2),bottom:G.padding}).appendTo(d);break;case"float":A.css("left",parseInt((A.width()-c.width-40)/2,10)*-1).appendTo(M);break;default:A.css({width:c.width-(G.padding*2),paddingLeft:G.padding,paddingRight:G.padding}).appendTo(M);break}A.hide()},g=function(){if(G.enableEscapeButton||G.enableKeyboardNav){B(document).bind("keydown.fb",function(V){if(V.keyCode==27&&G.enableEscapeButton){V.preventDefault();B.fancybox.close()}else{if((V.keyCode==37||V.keyCode==39)&&G.enableKeyboardNav&&V.target.tagName!=="INPUT"&&V.target.tagName!=="TEXTAREA"&&V.target.tagName!=="SELECT"){V.preventDefault();B.fancybox[V.keyCode==37?"prev":"next"]()}}})}if(!G.showNavArrows){O.hide();z.hide();return}if((G.cyclic&&y.length>1)||e!==0){O.show()}if((G.cyclic&&y.length>1)||e!=(y.length-1)){z.show()}},v=function(){if(!B.support.opacity){m.get(0).style.removeAttribute("filter");M.get(0).style.removeAttribute("filter")}if(H.autoDimensions){m.css("height","auto")}M.css("height","auto");if(t&&t.length){A.show()}if(G.showCloseButton){J.show()}g();if(G.hideOnContentClick){m.bind("click",B.fancybox.close)}if(G.hideOnOverlayClick){Q.bind("click",B.fancybox.close)}B(window).bind("resize.fb",B.fancybox.resize);if(G.centerOnScroll){B(window).bind("scroll.fb",B.fancybox.center)}if(G.type=="iframe"){B('<iframe id="fancybox-frame" name="fancybox-frame'+new Date().getTime()+'" frameborder="0" hspace="0" '+(B.browser.msie?'allowtransparency="true""':"")+' scrolling="'+H.scrolling+'" src="'+G.href+'"></iframe>').appendTo(m)}M.show();P=false;B.fancybox.center();G.onComplete(y,e,G);K()},K=function(){var V,W;if((y.length-1)>e){V=y[e+1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}if(e>0){V=y[e-1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}},U=function(W){var V={width:parseInt(b.width+(c.width-b.width)*W,10),height:parseInt(b.height+(c.height-b.height)*W,10),top:parseInt(b.top+(c.top-b.top)*W,10),left:parseInt(b.left+(c.left-b.left)*W,10)};if(typeof c.opacity!=="undefined"){V.opacity=W<0.5?0.5:W}M.css(V);m.css({width:V.width-G.padding*2,height:V.height-(h*W)-G.padding*2})},u=function(){return[B(window).width()-(G.margin*2),B(window).height()-(G.margin*2),B(document).scrollLeft()+G.margin,B(document).scrollTop()+G.margin]},R=function(){var V=u(),Z={},W=G.autoScale,X=G.padding*2,Y;if(G.width.toString().indexOf("%")>-1){Z.width=parseInt((V[0]*parseFloat(G.width))/100,10)}else{Z.width=G.width+X}if(G.height.toString().indexOf("%")>-1){Z.height=parseInt((V[1]*parseFloat(G.height))/100,10)}else{Z.height=G.height+X}if(W&&(Z.width>V[0]||Z.height>V[1])){if(H.type=="image"||H.type=="swf"){Y=(G.width)/(G.height);if((Z.width)>V[0]){Z.width=V[0];Z.height=parseInt(((Z.width-X)/Y)+X,10)}if((Z.height)>V[1]){Z.height=V[1];Z.width=parseInt(((Z.height-X)*Y)+X,10)}}else{Z.width=Math.min(Z.width,V[0]);Z.height=Math.min(Z.height,V[1])}}Z.top=parseInt(Math.max(V[3]-20,V[3]+((V[1]-Z.height-40)*0.5)),10);Z.left=parseInt(Math.max(V[2]-20,V[2]+((V[0]-Z.width-40)*0.5)),10);return Z},q=function(V){var W=V.offset();W.top+=parseInt(V.css("paddingTop"),10)||0;W.left+=parseInt(V.css("paddingLeft"),10)||0;W.top+=parseInt(V.css("border-top-width"),10)||0;W.left+=parseInt(V.css("border-left-width"),10)||0;W.width=V.width();W.height=V.height();return W},I=function(){var Y=H.orig?B(H.orig):false,X={},W,V;if(Y&&Y.length){W=q(Y);X={width:W.width+(G.padding*2),height:W.height+(G.padding*2),top:W.top-G.padding-20,left:W.left-G.padding-20}}else{V=u();X={width:G.padding*2,height:G.padding*2,top:parseInt(V[3]+V[1]*0.5,10),left:parseInt(V[2]+V[0]*0.5,10)}}return X},a=function(){if(!T.is(":visible")){clearInterval(p);return}B("div",T).css("top",(N*-40)+"px");N=(N+1)%12};B.fn.fancybox=function(V){if(!B(this).length){return this}B(this).data("fancybox",B.extend({},V,(B.metadata?B(this).metadata():{}))).unbind("click.fb").bind("click.fb",function(X){X.preventDefault();if(P){return}P=true;B(this).blur();j=[];C=0;var W=B(this).attr("rel")||"";if(!W||W==""||W==="nofollow"){j.push(this)}else{j=B("a[rel="+W+"], area[rel="+W+"]");C=j.index(this)}w();return});return this};B.fancybox=function(Y){var X;if(P){return}P=true;X=typeof arguments[1]!=="undefined"?arguments[1]:{};j=[];C=parseInt(X.index,10)||0;if(B.isArray(Y)){for(var W=0,V=Y.length;W<V;W++){if(typeof Y[W]=="object"){B(Y[W]).data("fancybox",B.extend({},X,Y[W]))}else{Y[W]=B({}).data("fancybox",B.extend({content:Y[W]},X))}}j=jQuery.merge(j,Y)}else{if(typeof Y=="object"){B(Y).data("fancybox",B.extend({},X,Y))}else{Y=B({}).data("fancybox",B.extend({content:Y},X))}j.push(Y)}if(C>j.length||C<0){C=0}w()};B.fancybox.showActivity=function(){clearInterval(p);T.show();p=setInterval(a,66)};B.fancybox.hideActivity=function(){T.hide()};B.fancybox.next=function(){return B.fancybox.pos(e+1)};B.fancybox.prev=function(){return B.fancybox.pos(e-1)};B.fancybox.pos=function(V){if(P){return}V=parseInt(V);j=y;if(V>-1&&V<y.length){C=V;w()}else{if(G.cyclic&&y.length>1){C=V>=y.length?0:y.length-1;w()}}return};B.fancybox.cancel=function(){if(P){return}P=true;B.event.trigger("fancybox-cancel");r();H.onCancel(j,C,H);P=false};B.fancybox.close=function(){if(P||M.is(":hidden")){return}P=true;if(G&&false===G.onCleanup(y,e,G)){P=false;return}r();B(J.add(O).add(z)).hide();B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");m.find("iframe").attr("src",S&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");if(G.titlePosition!=="inside"){A.empty()}M.stop();function V(){Q.fadeOut("fast");A.empty().hide();M.hide();B.event.trigger("fancybox-cleanup");m.empty();G.onClosed(y,e,G);y=H=[];e=C=0;G=H={};P=false}if(G.transitionOut=="elastic"){b=I();var W=M.position();c={top:W.top,left:W.left,width:M.width(),height:M.height()};if(G.opacity){c.opacity=1}A.empty().hide();s.prop=1;B(s).animate({prop:0},{duration:G.speedOut,easing:G.easingOut,step:U,complete:V})}else{M.fadeOut(G.transitionOut=="none"?0:G.speedOut,V)}};B.fancybox.resize=function(){if(Q.is(":visible")){Q.css("height",B(document).height())}B.fancybox.center(true)};B.fancybox.center=function(){var V,W;if(P){return}W=arguments[0]===true?1:0;V=u();if(!W&&(M.width()>V[0]||M.height()>V[1])){return}M.stop().animate({top:parseInt(Math.max(V[3]-20,V[3]+((V[1]-m.height()-40)*0.5)-G.padding)),left:parseInt(Math.max(V[2]-20,V[2]+((V[0]-m.width()-40)*0.5)-G.padding))},typeof arguments[0]=="number"?arguments[0]:200)};B.fancybox.init=function(){if(B("#fancybox-wrap").length){return}B("body").append(L=B('<div id="fancybox-tmp"></div>'),T=B('<div id="fancybox-loading"><div></div></div>'),Q=B('<div id="fancybox-overlay"></div>'),M=B('<div id="fancybox-wrap"></div>'));d=B('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(M);d.append(m=B('<div id="fancybox-content"></div>'),J=B('<a id="fancybox-close"></a>'),A=B('<div id="fancybox-title"></div>'),O=B('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),z=B('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));J.click(B.fancybox.close);T.click(B.fancybox.cancel);O.click(function(V){V.preventDefault();B.fancybox.prev()});z.click(function(V){V.preventDefault();B.fancybox.next()});if(B.fn.mousewheel){M.bind("mousewheel.fb",function(V,W){if(P){V.preventDefault()}else{if(B(V.target).get(0).clientHeight==0||B(V.target).get(0).scrollHeight===B(V.target).get(0).clientHeight){V.preventDefault();B.fancybox[W>0?"prev":"next"]()}}})}if(!B.support.opacity){M.addClass("fancybox-ie")}if(S){T.addClass("fancybox-ie6");M.addClass("fancybox-ie6");B('<iframe id="fancybox-hide-sel-frame" src="'+(/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank")+'" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(d)}};B.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};B(document).ready(function(){B.fancybox.init()})})(jQuery); \ No newline at end of file
+(function(B){var L,T,Q,M,d,m,J,A,O,z,C=0,H={},j=[],e=0,G={},y=[],f=null,o=new Image(),i=/\.(jpg|gif|png|bmp|jpeg)(.*)?$/i,k=/[^\.]\.(swf)\s*$/i,p,N=1,h=0,t="",b,c,P=false,s=B.extend(B("<div/>")[0],{prop:0}),S=B.browser.msie&&B.browser.version<7&&!window.XMLHttpRequest,r=function(){T.hide();o.onerror=o.onload=null;if(f){f.abort()}L.empty()},x=function(){if(false===H.onError(j,C,H)){T.hide();P=false;return}H.titleShow=false;H.width="auto";H.height="auto";L.html('<p id="fancybox-error">The requested content cannot be loaded.<br />Please try again later.</p>');n()},w=function(){var Z=j[C],W,Y,ab,aa,V,X;r();H=B.extend({},B.fn.fancybox.defaults,(typeof B(Z).data("fancybox")=="undefined"?H:B(Z).data("fancybox")));X=H.onStart(j,C,H);if(X===false){P=false;return}else{if(typeof X=="object"){H=B.extend(H,X)}}ab=H.title||(Z.nodeName?B(Z).attr("title"):Z.title)||"";if(Z.nodeName&&!H.orig){H.orig=B(Z).children("img:first").length?B(Z).children("img:first"):B(Z)}if(ab===""&&H.orig&&H.titleFromAlt){ab=H.orig.attr("alt")}ab=ab.replace(/</,"&lt;").replace(/>/,"&gt;");W=H.href||(Z.nodeName?B(Z).attr("href"):Z.href)||null;if((/^(?:javascript)/i).test(W)||W=="#"){W=null}if(H.type){Y=H.type;if(!W){W=H.content}}else{if(H.content){Y="html"}else{if(W){if(W.match(i)){Y="image"}else{if(W.match(k)){Y="swf"}else{if(B(Z).hasClass("iframe")){Y="iframe"}else{if(W.indexOf("#")===0){Y="inline"}}}}}}}if(!Y){x();return}if(Y=="inline"){Z=W.substr(W.indexOf("#"));Y=B(Z).length>0?"inline":"ajax"}H.type=Y;H.href=W;H.title=ab;if(H.autoDimensions){if(H.type=="html"||H.type=="inline"||H.type=="ajax"){H.width="auto";H.height="auto"}else{H.autoDimensions=false}}if(H.modal){H.overlayShow=true;H.hideOnOverlayClick=false;H.hideOnContentClick=false;H.enableEscapeButton=false;H.showCloseButton=false}H.padding=parseInt(H.padding,10);H.margin=parseInt(H.margin,10);L.css("padding",(H.padding+H.margin));B(".fancybox-inline-tmp").unbind("fancybox-cancel").bind("fancybox-change",function(){B(this).replaceWith(m.children())});switch(Y){case"html":L.html(H.content);n();break;case"inline":if(B(Z).parent().is("#fancybox-content")===true){P=false;return}B('<div class="fancybox-inline-tmp" />').hide().insertBefore(B(Z)).bind("fancybox-cleanup",function(){B(this).replaceWith(m.children())}).bind("fancybox-cancel",function(){B(this).replaceWith(L.children())});B(Z).appendTo(L);n();break;case"image":P=false;B.fancybox.showActivity();o=new Image();o.onerror=function(){x()};o.onload=function(){P=true;o.onerror=o.onload=null;F()};o.src=W;break;case"swf":H.scrolling="no";aa='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="'+H.width+'" height="'+H.height+'"><param name="movie" value="'+W+'"></param>';V="";B.each(H.swf,function(ac,ad){aa+='<param name="'+ac+'" value="'+ad+'"></param>';V+=" "+ac+'="'+ad+'"'});aa+='<embed src="'+W+'" type="application/x-shockwave-flash" width="'+H.width+'" height="'+H.height+'"'+V+"></embed></object>";L.html(aa);n();break;case"ajax":P=false;B.fancybox.showActivity();H.ajax.win=H.ajax.success;f=B.ajax(B.extend({},H.ajax,{url:W,data:H.ajax.data||{},error:function(ac,ae,ad){if(ac.status>0){x()}},success:function(ad,af,ac){var ae=typeof ac=="object"?ac:f;if(ae.status==200){if(typeof H.ajax.win=="function"){X=H.ajax.win(W,ad,af,ac);if(X===false){T.hide();return}else{if(typeof X=="string"||typeof X=="object"){ad=X}}}L.html(ad);n()}}}));break;case"iframe":E();break}},n=function(){var V=H.width,W=H.height;if(V.toString().indexOf("%")>-1){V=parseInt((B(window).width()-(H.margin*2))*parseFloat(V)/100,10)+"px"}else{V=V=="auto"?"auto":V+"px"}if(W.toString().indexOf("%")>-1){W=parseInt((B(window).height()-(H.margin*2))*parseFloat(W)/100,10)+"px"}else{W=W=="auto"?"auto":W+"px"}L.wrapInner('<div style="width:'+V+";height:"+W+";overflow: "+(H.scrolling=="auto"?"auto":(H.scrolling=="yes"?"scroll":"hidden"))+';position:relative;"></div>');H.width=L.width();H.height=L.height();E()},F=function(){H.width=o.width;H.height=o.height;B("<img />").attr({id:"fancybox-img",src:o.src,alt:H.title}).appendTo(L);E()},E=function(){var W,V;T.hide();if(M.is(":visible")&&false===G.onCleanup(y,e,G)){B.event.trigger("fancybox-cancel");P=false;return}P=true;B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");if(M.is(":visible")&&G.titlePosition!=="outside"){M.css("height",M.height())}y=j;e=C;G=H;if(G.overlayShow){Q.css({"background-color":G.overlayColor,opacity:G.overlayOpacity,cursor:G.hideOnOverlayClick?"pointer":"auto",height:B(document).height()});if(!Q.is(":visible")){if(S){B("select:not(#fancybox-tmp select)").filter(function(){return this.style.visibility!=="hidden"}).css({visibility:"hidden"}).one("fancybox-cleanup",function(){this.style.visibility="inherit"})}Q.show()}}else{Q.hide()}c=R();l();if(M.is(":visible")){B(J.add(O).add(z)).hide();W=M.position(),b={top:W.top,left:W.left,width:M.width(),height:M.height()};V=(b.width==c.width&&b.height==c.height);m.fadeTo(G.changeFade,0.3,function(){var X=function(){m.html(L.contents()).fadeTo(G.changeFade,1,v)};B.event.trigger("fancybox-change");m.empty().removeAttr("filter").css({"border-width":G.padding,width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2});if(V){X()}else{s.prop=0;B(s).animate({prop:1},{duration:G.changeSpeed,easing:G.easingChange,step:U,complete:X})}});return}M.removeAttr("style");m.css("border-width",G.padding);if(G.transitionIn=="elastic"){b=I();m.html(L.contents());M.show();if(G.opacity){c.opacity=0}s.prop=0;B(s).animate({prop:1},{duration:G.speedIn,easing:G.easingIn,step:U,complete:v});return}if(G.titlePosition=="inside"&&h>0){A.show()}m.css({width:c.width-G.padding*2,height:H.autoDimensions?"auto":c.height-h-G.padding*2}).html(L.contents());M.css(c).fadeIn(G.transitionIn=="none"?0:G.speedIn,v)},D=function(V){if(V&&V.length){if(G.titlePosition=="float"){return'<table id="fancybox-title-float-wrap" cellpadding="0" cellspacing="0"><tr><td id="fancybox-title-float-left"></td><td id="fancybox-title-float-main">'+V+'</td><td id="fancybox-title-float-right"></td></tr></table>'}return'<div id="fancybox-title-'+G.titlePosition+'">'+V+"</div>"}return false},l=function(){t=G.title||"";h=0;A.empty().removeAttr("style").removeClass();if(G.titleShow===false){A.hide();return}t=B.isFunction(G.titleFormat)?G.titleFormat(t,y,e,G):D(t);if(!t||t===""){A.hide();return}A.addClass("fancybox-title-"+G.titlePosition).html(t).appendTo("body").show();switch(G.titlePosition){case"inside":A.css({width:c.width-(G.padding*2),marginLeft:G.padding,marginRight:G.padding});h=A.outerHeight(true);A.appendTo(d);c.height+=h;break;case"over":A.css({marginLeft:G.padding,width:c.width-(G.padding*2),bottom:G.padding}).appendTo(d);break;case"float":A.css("left",parseInt((A.width()-c.width-40)/2,10)*-1).appendTo(M);break;default:A.css({width:c.width-(G.padding*2),paddingLeft:G.padding,paddingRight:G.padding}).appendTo(M);break}A.hide()},g=function(){if(G.enableEscapeButton||G.enableKeyboardNav){B(document).bind("keydown.fb",function(V){if(V.keyCode==27&&G.enableEscapeButton){V.preventDefault();B.fancybox.close()}else{if((V.keyCode==37||V.keyCode==39)&&G.enableKeyboardNav&&V.target.tagName!=="INPUT"&&V.target.tagName!=="TEXTAREA"&&V.target.tagName!=="SELECT"){V.preventDefault();B.fancybox[V.keyCode==37?"prev":"next"]()}}})}if(!G.showNavArrows){O.hide();z.hide();return}if((G.cyclic&&y.length>1)||e!==0){O.show()}if((G.cyclic&&y.length>1)||e!=(y.length-1)){z.show()}},v=function(){if(!B.support.opacity){m.get(0).style.removeAttribute("filter");M.get(0).style.removeAttribute("filter")}if(H.autoDimensions){m.css("height","auto")}M.css("height","auto");if(t&&t.length){A.show()}if(G.showCloseButton){J.show()}g();if(G.hideOnContentClick){m.bind("click",B.fancybox.close)}if(G.hideOnOverlayClick){Q.bind("click",B.fancybox.close)}B(window).bind("resize.fb",B.fancybox.resize);if(G.centerOnScroll){B(window).bind("scroll.fb",B.fancybox.center)}if(G.type=="iframe"){B('<iframe id="fancybox-frame" name="fancybox-frame'+new Date().getTime()+'" frameborder="0" hspace="0" '+(B.browser.msie?'allowtransparency="true""':"")+' scrolling="'+H.scrolling+'" src="'+G.href+'"></iframe>').appendTo(m)}M.show();P=false;B.fancybox.center();G.onComplete(y,e,G);K()},K=function(){var V,W;if((y.length-1)>e){V=y[e+1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}if(e>0){V=y[e-1].href;if(typeof V!=="undefined"&&V.match(i)){W=new Image();W.src=V}}},U=function(W){var V={width:parseInt(b.width+(c.width-b.width)*W,10),height:parseInt(b.height+(c.height-b.height)*W,10),top:parseInt(b.top+(c.top-b.top)*W,10),left:parseInt(b.left+(c.left-b.left)*W,10)};if(typeof c.opacity!=="undefined"){V.opacity=W<0.5?0.5:W}M.css(V);m.css({width:V.width-G.padding*2,height:V.height-(h*W)-G.padding*2})},u=function(){return[B(window).width()-(G.margin*2),B(window).height()-(G.margin*2),B(document).scrollLeft()+G.margin,B(document).scrollTop()+G.margin]},R=function(){var V=u(),Z={},W=G.autoScale,X=G.padding*2,Y;if(G.width.toString().indexOf("%")>-1){Z.width=parseInt((V[0]*parseFloat(G.width))/100,10)}else{Z.width=G.width+X}if(G.height.toString().indexOf("%")>-1){Z.height=parseInt((V[1]*parseFloat(G.height))/100,10)}else{Z.height=G.height+X}if(W&&(Z.width>V[0]||Z.height>V[1])){if(H.type=="image"||H.type=="swf"){Y=(G.width)/(G.height);if((Z.width)>V[0]){Z.width=V[0];Z.height=parseInt(((Z.width-X)/Y)+X,10)}if((Z.height)>V[1]){Z.height=V[1];Z.width=parseInt(((Z.height-X)*Y)+X,10)}}else{Z.width=Math.min(Z.width,V[0]);Z.height=Math.min(Z.height,V[1])}}Z.top=parseInt(Math.max(V[3]-20,V[3]+((V[1]-Z.height-40)*0.5)),10);Z.left=parseInt(Math.max(V[2]-20,V[2]+((V[0]-Z.width-40)*0.5)),10);return Z},q=function(V){var W=V.offset();W.top+=parseInt(V.css("paddingTop"),10)||0;W.left+=parseInt(V.css("paddingLeft"),10)||0;W.top+=parseInt(V.css("border-top-width"),10)||0;W.left+=parseInt(V.css("border-left-width"),10)||0;W.width=V.width();W.height=V.height();return W},I=function(){var Y=H.orig?B(H.orig):false,X={},W,V;if(Y&&Y.length){W=q(Y);X={width:W.width+(G.padding*2),height:W.height+(G.padding*2),top:W.top-G.padding-20,left:W.left-G.padding-20}}else{V=u();X={width:G.padding*2,height:G.padding*2,top:parseInt(V[3]+V[1]*0.5,10),left:parseInt(V[2]+V[0]*0.5,10)}}return X},a=function(){if(!T.is(":visible")){clearInterval(p);return}B("div",T).css("top",(N*-40)+"px");N=(N+1)%12};B.fn.fancybox=function(V){if(!B(this).length){return this}B(this).data("fancybox",B.extend({},V,(B.metadata?B(this).metadata():{}))).unbind("click.fb").bind("click.fb",function(X){X.preventDefault();if(P){return}P=true;B(this).blur();j=[];C=0;var W=B(this).attr("rel")||"";if(!W||W==""||W==="nofollow"){j.push(this)}else{j=B("a[rel="+W+"], area[rel="+W+"]");C=j.index(this)}w();return});return this};B.fancybox=function(Y){var X;if(P){return}P=true;X=typeof arguments[1]!=="undefined"?arguments[1]:{};j=[];C=parseInt(X.index,10)||0;if(B.isArray(Y)){for(var W=0,V=Y.length;W<V;W++){if(typeof Y[W]=="object"){B(Y[W]).data("fancybox",B.extend({},X,Y[W]))}else{Y[W]=B({}).data("fancybox",B.extend({content:Y[W]},X))}}j=jQuery.merge(j,Y)}else{if(typeof Y=="object"){B(Y).data("fancybox",B.extend({},X,Y))}else{Y=B({}).data("fancybox",B.extend({content:Y},X))}j.push(Y)}if(C>j.length||C<0){C=0}w()};B.fancybox.showActivity=function(){clearInterval(p);T.show();p=setInterval(a,66)};B.fancybox.hideActivity=function(){T.hide()};B.fancybox.next=function(){return B.fancybox.pos(e+1)};B.fancybox.prev=function(){return B.fancybox.pos(e-1)};B.fancybox.pos=function(V){if(P){return}V=parseInt(V);j=y;if(V>-1&&V<y.length){C=V;w()}else{if(G.cyclic&&y.length>1){C=V>=y.length?0:y.length-1;w()}}return};B.fancybox.cancel=function(){if(P){return}P=true;B.event.trigger("fancybox-cancel");r();H.onCancel(j,C,H);P=false};B.fancybox.close=function(){if(P||M.is(":hidden")){return}P=true;if(G&&false===G.onCleanup(y,e,G)){P=false;return}r();B(J.add(O).add(z)).hide();B(m.add(Q)).unbind();B(window).unbind("resize.fb scroll.fb");B(document).unbind("keydown.fb");m.find("iframe").attr("src",S&&/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank");if(G.titlePosition!=="inside"){A.empty()}M.stop();function V(){Q.fadeOut("fast");A.empty().hide();M.hide();B.event.trigger("fancybox-cleanup");m.empty();G.onClosed(y,e,G);y=H=[];e=C=0;G=H={};P=false}if(G.transitionOut=="elastic"){b=I();var W=M.position();c={top:W.top,left:W.left,width:M.width(),height:M.height()};if(G.opacity){c.opacity=1}A.empty().hide();s.prop=1;B(s).animate({prop:0},{duration:G.speedOut,easing:G.easingOut,step:U,complete:V})}else{M.fadeOut(G.transitionOut=="none"?0:G.speedOut,V)}};B.fancybox.resize=function(){if(Q.is(":visible")){Q.css("height",B(document).height())}B.fancybox.center(true)};B.fancybox.center=function(){var V,W;if(P){return}W=arguments[0]===true?1:0;V=u();if(!W&&(M.width()>V[0]||M.height()>V[1])){return}M.stop().animate({top:parseInt(Math.max(V[3]-20,V[3]+((V[1]-m.height()-40)*0.5)-G.padding)),left:parseInt(Math.max(V[2]-20,V[2]+((V[0]-m.width()-40)*0.5)-G.padding))},typeof arguments[0]=="number"?arguments[0]:200)};B.fancybox.init=function(){if(B("#fancybox-wrap").length){return}B("body").append(L=B('<div id="fancybox-tmp"></div>'),T=B('<div id="fancybox-loading"><div></div></div>'),Q=B('<div id="fancybox-overlay"></div>'),M=B('<div id="fancybox-wrap"></div>'));d=B('<div id="fancybox-outer"></div>').append('<div class="fancybox-bg" id="fancybox-bg-n"></div><div class="fancybox-bg" id="fancybox-bg-ne"></div><div class="fancybox-bg" id="fancybox-bg-e"></div><div class="fancybox-bg" id="fancybox-bg-se"></div><div class="fancybox-bg" id="fancybox-bg-s"></div><div class="fancybox-bg" id="fancybox-bg-sw"></div><div class="fancybox-bg" id="fancybox-bg-w"></div><div class="fancybox-bg" id="fancybox-bg-nw"></div>').appendTo(M);d.append(m=B('<div id="fancybox-content"></div>'),J=B('<a id="fancybox-close"></a>'),A=B('<div id="fancybox-title"></div>'),O=B('<a href="javascript:;" id="fancybox-left"><span class="fancy-ico" id="fancybox-left-ico"></span></a>'),z=B('<a href="javascript:;" id="fancybox-right"><span class="fancy-ico" id="fancybox-right-ico"></span></a>'));J.click(B.fancybox.close);T.click(B.fancybox.cancel);O.click(function(V){V.preventDefault();B.fancybox.prev()});z.click(function(V){V.preventDefault();B.fancybox.next()});if(B.fn.mousewheel){M.bind("mousewheel.fb",function(V,W){if(P){V.preventDefault()}else{if(B(V.target).get(0).clientHeight==0||B(V.target).get(0).scrollHeight===B(V.target).get(0).clientHeight){V.preventDefault();B.fancybox[W>0?"prev":"next"]()}}})}if(!B.support.opacity){M.addClass("fancybox-ie")}if(S){T.addClass("fancybox-ie6");M.addClass("fancybox-ie6");B('<iframe id="fancybox-hide-sel-frame" src="'+(/^https/i.test(window.location.href||"")?"javascript:void(false)":"about:blank")+'" scrolling="no" border="0" frameborder="0" tabindex="-1"></iframe>').prependTo(d)}};B.fn.fancybox.defaults={padding:10,margin:40,opacity:false,modal:false,cyclic:false,scrolling:"auto",width:560,height:340,autoScale:true,autoDimensions:true,centerOnScroll:false,ajax:{},swf:{wmode:"transparent"},hideOnOverlayClick:true,hideOnContentClick:false,overlayShow:true,overlayOpacity:0.7,overlayColor:"#777",titleShow:true,titlePosition:"float",titleFormat:null,titleFromAlt:false,transitionIn:"fade",transitionOut:"fade",speedIn:300,speedOut:300,changeSpeed:300,changeFade:"fast",easingIn:"swing",easingOut:"swing",showCloseButton:true,showNavArrows:true,enableEscapeButton:true,enableKeyboardNav:true,onStart:function(){},onCancel:function(){},onComplete:function(){},onCleanup:function(){},onClosed:function(){},onError:function(){}};B(document).ready(function(){B.fancybox.init()})})(jQuery); \ No newline at end of file
diff --git a/apps/files_sharing/sharedstorage.php b/apps/files_sharing/sharedstorage.php
index 32fd2124429..fc0d272b54e 100644
--- a/apps/files_sharing/sharedstorage.php
+++ b/apps/files_sharing/sharedstorage.php
@@ -410,7 +410,7 @@ class OC_Filestorage_Shared extends OC_Filestorage_Common {
}
}
- public function hash($type, $path, $raw) {
+ public function hash($type, $path, $raw = false) {
$source = $this->getSource($path);
if ($source) {
$storage = OC_Filesystem::getStorage($source);
diff --git a/apps/gallery/l10n/de.php b/apps/gallery/l10n/de.php
index 6c3d9fc7389..cd580cf303c 100644
--- a/apps/gallery/l10n/de.php
+++ b/apps/gallery/l10n/de.php
@@ -1,9 +1,9 @@
<?php $TRANSLATIONS = array(
"Pictures" => "Bilder",
-"Settings" => "Einstellungen",
-"Rescan" => "Erneut Scannen",
-"Stop" => "Stopp",
-"Share" => "Teilen",
+"Share gallery" => "Galerie teilen",
+"Error: " => "Fehler:",
+"Internal error" => "Interner Fehler",
+"Slideshow" => "Slideshow",
"Back" => "Zurück",
"Remove confirmation" => "Bestätigung entfernen",
"Do you want to remove album" => "Soll das Album entfernt werden",
diff --git a/apps/gallery/l10n/es.php b/apps/gallery/l10n/es.php
index 03e8d6a4563..aa425a0bd04 100644
--- a/apps/gallery/l10n/es.php
+++ b/apps/gallery/l10n/es.php
@@ -1,9 +1,9 @@
<?php $TRANSLATIONS = array(
"Pictures" => "Imágenes",
-"Settings" => "Preferencias",
-"Rescan" => "Refrescar",
-"Stop" => "Parar",
-"Share" => "Compartir",
+"Share gallery" => "Compartir galería",
+"Error: " => "Fallo ",
+"Internal error" => "Fallo interno",
+"Slideshow" => "Presentación",
"Back" => "Atrás",
"Remove confirmation" => "Borrar confirmación",
"Do you want to remove album" => "¿Quieres eliminar el álbum",
diff --git a/apps/gallery/l10n/it.php b/apps/gallery/l10n/it.php
index e21a1d6524b..ef8d596e7eb 100644
--- a/apps/gallery/l10n/it.php
+++ b/apps/gallery/l10n/it.php
@@ -1,9 +1,9 @@
<?php $TRANSLATIONS = array(
"Pictures" => "Immagini",
-"Settings" => "Impostazioni",
-"Rescan" => "Nuova scansione",
-"Stop" => "Ferma",
-"Share" => "Condividi",
+"Share gallery" => "Condividi la galleria",
+"Error: " => "Errore: ",
+"Internal error" => "Errore interno",
+"Slideshow" => "Presentazione",
"Back" => "Indietro",
"Remove confirmation" => "Rimuovi conferma",
"Do you want to remove album" => "Vuoi rimuovere l'album",
diff --git a/apps/gallery/l10n/vi.php b/apps/gallery/l10n/vi.php
new file mode 100644
index 00000000000..d1d7fc64fca
--- /dev/null
+++ b/apps/gallery/l10n/vi.php
@@ -0,0 +1,11 @@
+<?php $TRANSLATIONS = array(
+"Pictures" => "Hình ảnh",
+"Share gallery" => "Chia sẻ gallery",
+"Error: " => "Lỗi :",
+"Internal error" => "Lỗi nội bộ",
+"Back" => "Trở lại",
+"Remove confirmation" => "Xóa xác nhận",
+"Do you want to remove album" => "Bạn muốn xóa album này ",
+"Change album name" => "Đổi tên album",
+"New album name" => "Tên album mới"
+);
diff --git a/apps/media/l10n/vi.php b/apps/media/l10n/vi.php
new file mode 100644
index 00000000000..01942ba173f
--- /dev/null
+++ b/apps/media/l10n/vi.php
@@ -0,0 +1,14 @@
+<?php $TRANSLATIONS = array(
+"Music" => "Âm nhạc",
+"Add album to playlist" => "Thêm album vào playlist",
+"Play" => "Play",
+"Pause" => "Tạm dừng",
+"Previous" => "Trang trước",
+"Next" => "Tiếp theo",
+"Mute" => "Tắt",
+"Unmute" => "Bật",
+"Rescan Collection" => "Quét lại bộ sưu tập",
+"Artist" => "Nghệ sỹ",
+"Album" => "Album",
+"Title" => "Tiêu đề"
+);
diff --git a/apps/user_ldap/appinfo/app.php b/apps/user_ldap/appinfo/app.php
index 330574c1d42..3c6da47d71a 100644
--- a/apps/user_ldap/appinfo/app.php
+++ b/apps/user_ldap/appinfo/app.php
@@ -21,15 +21,17 @@
*
*/
-require_once('apps/user_ldap/lib_ldap.php');
-require_once('apps/user_ldap/user_ldap.php');
-require_once('apps/user_ldap/group_ldap.php');
+OCP\App::registerAdmin('user_ldap', 'settings');
-OCP\App::registerAdmin('user_ldap','settings');
+$connector = new OCA\user_ldap\lib\Connection('user_ldap');
+$userBackend = new OCA\user_ldap\USER_LDAP();
+$userBackend->setConnector($connector);
+$groupBackend = new OCA\user_ldap\GROUP_LDAP();
+$groupBackend->setConnector($connector);
// register user backend
-OC_User::useBackend( 'LDAP' );
-OC_Group::useBackend( new OC_GROUP_LDAP() );
+OC_User::useBackend($userBackend);
+OC_Group::useBackend($groupBackend);
// add settings page to navigation
$entry = array(
diff --git a/apps/user_ldap/group_ldap.php b/apps/user_ldap/group_ldap.php
index d438c7d84df..b9f4bdf1990 100644
--- a/apps/user_ldap/group_ldap.php
+++ b/apps/user_ldap/group_ldap.php
@@ -21,24 +21,22 @@
*
*/
-class OC_GROUP_LDAP extends OC_Group_Backend {
-// //group specific settings
- protected $ldapGroupFilter;
- protected $ldapGroupMemberAssocAttr;
- protected $configured = false;
+namespace OCA\user_ldap;
+
+class GROUP_LDAP extends lib\Access implements \OCP\GroupInterface {
+ protected $enabled = false;
protected $_group_user = array();
protected $_user_groups = array();
protected $_group_users = array();
protected $_groups = array();
- public function __construct() {
- $this->ldapGroupFilter = OCP\Config::getAppValue('user_ldap', 'ldap_group_filter', '(objectClass=posixGroup)');
- $this->ldapGroupMemberAssocAttr = OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember');
-
- if(!empty($this->ldapGroupFilter) && !empty($this->ldapGroupMemberAssocAttr)) {
- $this->configured = true;
+ public function setConnector(lib\Connection &$connection) {
+ parent::setConnector($connection);
+ if(empty($this->connection->ldapGroupFilter) || empty($this->connection->ldapGroupMemberAssocAttr)) {
+ $this->enabled = false;
}
+ $this->enabled = true;
}
/**
@@ -50,31 +48,31 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Checks whether the user is member of a group or not.
*/
public function inGroup($uid, $gid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
return false;
}
if(isset($this->_group_user[$gid][$uid])) {
return $this->_group_user[$gid][$uid];
}
- $dn_user = OC_LDAP::username2dn($uid);
- $dn_group = OC_LDAP::groupname2dn($gid);
+ $dn_user = $this->username2dn($uid);
+ $dn_group = $this->groupname2dn($gid);
// just in case
if(!$dn_group || !$dn_user) {
return false;
}
//usually, LDAP attributes are said to be case insensitive. But there are exceptions of course.
- $members = OC_LDAP::readAttribute($dn_group, $this->ldapGroupMemberAssocAttr);
+ $members = $this->readAttribute($dn_group, $this->connection->ldapGroupMemberAssocAttr);
if(!$members) {
return false;
}
//extra work if we don't get back user DNs
//TODO: this can be done with one LDAP query
- if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
+ if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
$dns = array();
foreach($members as $mid) {
- $filter = str_replace('%uid', $mid, OC_LDAP::conf('ldapLoginFilter'));
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = str_replace('%uid', $mid, $this->connection->ldapLoginFilter);
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
continue;
}
@@ -96,36 +94,37 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* if the user exists at all.
*/
public function getUserGroups($uid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(isset($this->_user_groups[$uid])) {
return $this->_user_groups[$uid];
}
- $userDN = OC_LDAP::username2dn($uid);
+ $userDN = $this->username2dn($uid);
if(!$userDN) {
$this->_user_groups[$uid] = array();
return array();
}
//uniqueMember takes DN, memberuid the uid, so we need to distinguish
- if((strtolower($this->ldapGroupMemberAssocAttr) == 'uniquemember')
- || (strtolower($this->ldapGroupMemberAssocAttr) == 'member')) {
+ if((strtolower($this->connection->ldapGroupMemberAssocAttr) == 'uniquemember')
+ || (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'member')
+ ) {
$uid = $userDN;
- } else if(strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid') {
- $result = OC_LDAP::readAttribute($userDN, 'uid');
+ } else if(strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid') {
+ $result = $this->readAttribute($userDN, 'uid');
$uid = $result[0];
} else {
// just in case
$uid = $userDN;
}
- $filter = OC_LDAP::combineFilterWithAnd(array(
- $this->ldapGroupFilter,
- $this->ldapGroupMemberAssocAttr.'='.$uid
+ $filter = $this->combineFilterWithAnd(array(
+ $this->connection->ldapGroupFilter,
+ $this->connection->ldapGroupMemberAssocAttr.'='.$uid
));
- $groups = OC_LDAP::fetchListOfGroups($filter, array(OC_LDAP::conf('ldapGroupDisplayName'),'dn'));
- $this->_user_groups[$uid] = array_unique(OC_LDAP::ownCloudGroupNames($groups), SORT_LOCALE_STRING);
+ $groups = $this->fetchListOfGroups($filter, array($this->connection->ldapGroupDisplayName,'dn'));
+ $this->_user_groups[$uid] = array_unique($this->ownCloudGroupNames($groups), SORT_LOCALE_STRING);
return $this->_user_groups[$uid];
}
@@ -135,44 +134,44 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* @returns array with user ids
*/
public function usersInGroup($gid) {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(isset($this->_group_users[$gid])) {
return $this->_group_users[$gid];
}
- $groupDN = OC_LDAP::groupname2dn($gid);
+ $groupDN = $this->groupname2dn($gid);
if(!$groupDN) {
$this->_group_users[$gid] = array();
return array();
}
- $members = OC_LDAP::readAttribute($groupDN, $this->ldapGroupMemberAssocAttr);
+ $members = $this->readAttribute($groupDN, $this->connection->ldapGroupMemberAssocAttr);
if(!$members) {
$this->_group_users[$gid] = array();
return array();
}
$result = array();
- $isMemberUid = (strtolower($this->ldapGroupMemberAssocAttr) == 'memberuid');
+ $isMemberUid = (strtolower($this->connection->ldapGroupMemberAssocAttr) == 'memberuid');
foreach($members as $member) {
if($isMemberUid) {
- $filter = OCP\Util::mb_str_replace('%uid', $member, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = \OCP\Util::mb_str_replace('%uid', $member, $this->connection->ldapLoginFilter, 'UTF-8');
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
continue;
}
- $result[] = OC_LDAP::dn2username($ldap_users[0]);
+ $result[] = $this->dn2username($ldap_users[0]);
continue;
} else {
- if($ocname = OC_LDAP::dn2username($member)){
+ if($ocname = $this->dn2username($member)) {
$result[] = $ocname;
}
}
}
if(!$isMemberUid) {
- $result = array_intersect($result, OCP\User::getUsers());
+ $result = array_intersect($result, \OCP\User::getUsers());
}
$this->_group_users[$gid] = array_unique($result, SORT_LOCALE_STRING);
return $this->_group_users[$gid];
@@ -185,12 +184,12 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
* Returns a list with all groups
*/
public function getGroups() {
- if(!$this->configured) {
+ if(!$this->enabled) {
return array();
}
if(empty($this->_groups)) {
- $ldap_groups = OC_LDAP::fetchListOfGroups($this->ldapGroupFilter, array(OC_LDAP::conf('ldapGroupDisplayName'), 'dn'));
- $this->_groups = OC_LDAP::ownCloudGroupNames($ldap_groups);
+ $ldap_groups = $this->fetchListOfGroups($this->connection->ldapGroupFilter, array($this->connection->ldapGroupDisplayName, 'dn'));
+ $this->_groups = $this->ownCloudGroupNames($ldap_groups);
}
return $this->_groups;
}
@@ -203,4 +202,17 @@ class OC_GROUP_LDAP extends OC_Group_Backend {
public function groupExists($gid){
return in_array($gid, $this->getGroups());
}
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions) {
+ //always returns false, because possible actions are modifying actions. We do not write to LDAP, at least for now.
+ return false;
+ }
} \ No newline at end of file
diff --git a/apps/user_ldap/lib/access.php b/apps/user_ldap/lib/access.php
new file mode 100644
index 00000000000..19122b34c7d
--- /dev/null
+++ b/apps/user_ldap/lib/access.php
@@ -0,0 +1,597 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+abstract class Access {
+ protected $connection;
+
+ public function setConnector(Connection &$connection) {
+ $this->connection = $connection;
+ }
+
+ private function checkConnection() {
+ return ($this->connection instanceof Connection);
+ }
+
+ /**
+ * @brief reads a given attribute for an LDAP record identified by a DN
+ * @param $dn the record in question
+ * @param $attr the attribute that shall be retrieved
+ * @returns the values in an array on success, false otherwise
+ *
+ * Reads an attribute from an LDAP entry
+ */
+ public function readAttribute($dn, $attr) {
+ if(!$this->checkConnection()) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP Connector assigned, access impossible for readAttribute.', \OCP\Util::WARN);
+ return false;
+ }
+ $cr = $this->connection->getConnectionResource();
+ if(!is_resource($cr)) {
+ //LDAP not available
+ return false;
+ }
+ $rr = @ldap_read($cr, $dn, 'objectClass=*', array($attr));
+ if(!is_resource($rr)) {
+ \OCP\Util::writeLog('user_ldap', 'readAttribute failed for DN '.$dn, \OCP\Util::DEBUG);
+ //in case an error occurs , e.g. object does not exist
+ return false;
+ }
+ $er = ldap_first_entry($cr, $rr);
+ //LDAP attributes are not case sensitive
+ $result = \OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
+ $attr = mb_strtolower($attr, 'UTF-8');
+
+ if(isset($result[$attr]) && $result[$attr]['count'] > 0) {
+ $values = array();
+ for($i=0;$i<$result[$attr]['count'];$i++) {
+ $values[] = $this->resemblesDN($attr) ? $this->sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
+ }
+ return $values;
+ }
+ return false;
+ }
+
+ /**
+ * @brief checks wether the given attribute`s valua is probably a DN
+ * @param $attr the attribute in question
+ * @return if so true, otherwise false
+ */
+ private function resemblesDN($attr) {
+ $resemblingAttributes = array(
+ 'dn',
+ 'uniquemember',
+ 'member'
+ );
+ return in_array($attr, $resemblingAttributes);
+ }
+
+ /**
+ * @brief sanitizes a DN received from the LDAP server
+ * @param $dn the DN in question
+ * @return the sanitized DN
+ */
+ private function sanitizeDN($dn) {
+ //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
+ $dn = preg_replace('/([^\\\]),(\s+)/u', '\1,', $dn);
+
+ //make comparisons and everything work
+ $dn = mb_strtolower($dn, 'UTF-8');
+
+ return $dn;
+ }
+
+ /**
+ * gives back the database table for the query
+ */
+ private function getMapTable($isUser) {
+ if($isUser) {
+ return '*PREFIX*ldap_user_mapping';
+ } else {
+ return '*PREFIX*ldap_group_mapping';
+ }
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the group
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the group
+ */
+ public function groupname2dn($name) {
+ return $this->ocname2dn($name, false);
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name of the user
+ * @param $name the ownCloud name in question
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name of the user
+ */
+ public function username2dn($name) {
+ $dn = $this->ocname2dn($name, true);
+ if($dn) {
+ return $dn;
+ } else {
+ //fallback: user is not mapped
+ $filter = $this->combineFilterWithAnd(array(
+ $this->connection->ldapUserFilter,
+ $this->connection->ldapUserDisplayName . '=' . $name,
+ ));
+ $result = $this->searchUsers($filter, 'dn');
+ if(isset($result[0]['dn'])) {
+ $this->mapComponent($result[0], $name, true);
+ return $result[0];
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * @brief returns the LDAP DN for the given internal ownCloud name
+ * @param $name the ownCloud name in question
+ * @param $isUser is it a user? otherwise group
+ * @returns string with the LDAP DN on success, otherwise false
+ *
+ * returns the LDAP DN for the given internal ownCloud name
+ */
+ private function ocname2dn($name, $isUser) {
+ $table = $this->getMapTable($isUser);
+
+ $query = \OCP\DB::prepare('
+ SELECT ldap_dn
+ FROM '.$table.'
+ WHERE owncloud_name = ?
+ ');
+
+ $record = $query->execute(array($name))->fetchOne();
+ return $record;
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the group
+ * @param $dn the dn of the group object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud, false on DN outside of search DN
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the group
+ */
+ public function dn2groupname($dn, $ldapname = null) {
+ if(mb_strripos($dn, $this->connection->ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseGroups, 'UTF-8'))) {
+ return false;
+ }
+ return $this->dn2ocname($dn, $ldapname, false);
+ }
+
+ /**
+ * @brief returns the internal ownCloud name for the given LDAP DN of the user
+ * @param $dn the dn of the user object
+ * @param $ldapname optional, the display name of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
+ */
+ public function dn2username($dn, $ldapname = null) {
+ if(mb_strripos($dn, $this->connection->ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen($this->connection->ldapBaseUsers, 'UTF-8'))) {
+ return false;
+ }
+ return $this->dn2ocname($dn, $ldapname, true);
+ }
+
+ /**
+ * @brief returns an internal ownCloud name for the given LDAP DN
+ * @param $dn the dn of the user object
+ * @param $ldapname optional, the display name of the object
+ * @param $isUser optional, wether it is a user object (otherwise group assumed)
+ * @returns string with with the name to use in ownCloud
+ *
+ * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
+ */
+ public function dn2ocname($dn, $ldapname = null, $isUser = true) {
+ $dn = $this->sanitizeDN($dn);
+ $table = $this->getMapTable($isUser);
+ if($isUser) {
+ $nameAttribute = $this->connection->ldapUserDisplayName;
+ } else {
+ $nameAttribute = $this->connection->ldapGroupDisplayName;
+ }
+
+ $query = \OCP\DB::prepare('
+ SELECT owncloud_name
+ FROM '.$table.'
+ WHERE ldap_dn = ?
+ ');
+
+ $component = $query->execute(array($dn))->fetchOne();
+ if($component) {
+ return $component;
+ }
+
+ if(is_null($ldapname)) {
+ $ldapname = $this->readAttribute($dn, $nameAttribute);
+ $ldapname = $ldapname[0];
+ }
+ $ldapname = $this->sanitizeUsername($ldapname);
+
+ //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
+ if($this->mapComponent($dn, $ldapname, $isUser)) {
+ return $ldapname;
+ }
+
+ //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
+ $oc_name = $this->alternateOwnCloudName($ldapname, $dn);
+ if($this->mapComponent($dn, $oc_name, $isUser)) {
+ return $oc_name;
+ }
+
+ //TODO: do not simple die away!
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+
+ /**
+ * @brief gives back the user names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
+ * @returns an array with the user names to use in ownCloud
+ *
+ * gives back the user names as they are used ownClod internally
+ */
+ public function ownCloudUserNames($ldapUsers) {
+ return $this->ldap2ownCloudNames($ldapUsers, true);
+ }
+
+ /**
+ * @brief gives back the group names as they are used ownClod internally
+ * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
+ * @returns an array with the group names to use in ownCloud
+ *
+ * gives back the group names as they are used ownClod internally
+ */
+ public function ownCloudGroupNames($ldapGroups) {
+ return $this->ldap2ownCloudNames($ldapGroups, false);
+ }
+
+ private function ldap2ownCloudNames($ldapObjects, $isUsers) {
+ if($isUsers) {
+ $knownObjects = $this->mappedUsers();
+ $nameAttribute = $this->connection->ldapUserDisplayName;
+ } else {
+ $knownObjects = $this->mappedGroups();
+ $nameAttribute = $this->connection->ldapGroupDisplayName;
+ }
+ $ownCloudNames = array();
+
+ foreach($ldapObjects as $ldapObject) {
+ $key = \OCP\Util::recursiveArraySearch($knownObjects, $ldapObject['dn']);
+
+ //everything is fine when we know the group
+ if($key !== false) {
+ $ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
+ continue;
+ }
+
+ //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters.
+ $ocname = $this->sanitizeUsername($ldapObject[$nameAttribute]);
+ if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+ $ownCloudNames[] = $ocname;
+ continue;
+ }
+
+ //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
+ $ocname = $this->alternateOwnCloudName($ocname, $ldapObject['dn']);
+ if($this->mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
+ $ownCloudNames[] = $ocname;
+ continue;
+ }
+
+ //TODO: do not simple die away
+ //and this of course should never been thrown :)
+ throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
+ }
+ return $ownCloudNames;
+ }
+
+ /**
+ * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ * @param $name the display name of the object
+ * @param $dn the dn of the object
+ * @returns string with with the name to use in ownCloud
+ *
+ * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
+ */
+ private function alternateOwnCloudName($name, $dn) {
+ $ufn = ldap_dn2ufn($dn);
+ $name = $name . '@' . trim(\OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
+ $name = $this->sanitizeUsername($name);
+ return $name;
+ }
+
+ /**
+ * @brief retrieves all known groups from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known groups from the mappings table
+ */
+ private function mappedGroups() {
+ return $this->mappedComponents(false);
+ }
+
+ /**
+ * @brief retrieves all known users from the mappings table
+ * @returns array with the results
+ *
+ * retrieves all known users from the mappings table
+ */
+ private function mappedUsers() {
+ return $this->mappedComponents(true);
+ }
+
+ private function mappedComponents($isUsers) {
+ $table = $this->getMapTable($isUsers);
+
+ $query = \OCP\DB::prepare('
+ SELECT ldap_dn, owncloud_name
+ FROM '. $table
+ );
+
+ return $query->execute()->fetchAll();
+ }
+
+ /**
+ * @brief inserts a new user or group into the mappings table
+ * @param $dn the record in question
+ * @param $ocname the name to use in ownCloud
+ * @param $isUser is it a user or a group?
+ * @returns true on success, false otherwise
+ *
+ * inserts a new user or group into the mappings table
+ */
+ private function mapComponent($dn, $ocname, $isUser = true) {
+ $table = $this->getMapTable($isUser);
+ $dn = $this->sanitizeDN($dn);
+
+ $sqlAdjustment = '';
+ $dbtype = \OCP\Config::getSystemValue('dbtype');
+ if($dbtype == 'mysql') {
+ $sqlAdjustment = 'FROM dual';
+ }
+
+ $insert = \OCP\DB::prepare('
+ INSERT INTO '.$table.' (ldap_dn, owncloud_name)
+ SELECT ?,?
+ '.$sqlAdjustment.'
+ WHERE NOT EXISTS (
+ SELECT 1
+ FROM '.$table.'
+ WHERE ldap_dn = ?
+ OR owncloud_name = ? )
+ ');
+
+ $res = $insert->execute(array($dn, $ocname, $dn, $ocname));
+
+ if(\OCP\DB::isError($res)) {
+ return false;
+ }
+
+ $insRows = $res->numRows();
+
+ if($insRows == 0) {
+ return false;
+ }
+
+ return true;
+ }
+
+ public function fetchListOfUsers($filter, $attr) {
+ return $this->fetchList($this->searchUsers($filter, $attr), (count($attr) > 1));
+ }
+
+ public function fetchListOfGroups($filter, $attr) {
+ return $this->fetchList($this->searchGroups($filter, $attr), (count($attr) > 1));
+ }
+
+ private function fetchList($list, $manyAttributes) {
+ if(is_array($list)) {
+ if($manyAttributes) {
+ return $list;
+ } else {
+ return array_unique($list, SORT_LOCALE_STRING);
+ }
+ }
+
+ //error cause actually, maybe throw an exception in future.
+ return array();
+ }
+
+ /**
+ * @brief executes an LDAP search, optimized for Users
+ * @param $filter the LDAP filter for the search
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ public function searchUsers($filter, $attr = null) {
+ return $this->search($filter, $this->connection->ldapBaseUsers, $attr);
+ }
+
+ /**
+ * @brief executes an LDAP search, optimized for Groups
+ * @param $filter the LDAP filter for the search
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ public function searchGroups($filter, $attr = null) {
+ return $this->search($filter, $this->connection->ldapBaseGroups, $attr);
+ }
+
+ /**
+ * @brief executes an LDAP search
+ * @param $filter the LDAP filter for the search
+ * @param $base the LDAP subtree that shall be searched
+ * @param $attr optional, when a certain attribute shall be filtered out
+ * @returns array with the search result
+ *
+ * Executes an LDAP search
+ */
+ private function search($filter, $base, $attr = null) {
+ if(!is_null($attr) && !is_array($attr)) {
+ $attr = array(mb_strtolower($attr, 'UTF-8'));
+ }
+
+ // See if we have a resource
+ $link_resource = $this->connection->getConnectionResource();
+ if(is_resource($link_resource)) {
+ $sr = ldap_search($link_resource, $base, $filter, $attr);
+ $findings = ldap_get_entries($link_resource, $sr );
+
+ // if we're here, probably no connection resource is returned.
+ // to make ownCloud behave nicely, we simply give back an empty array.
+ if(is_null($findings)) {
+ return array();
+ }
+ } else {
+ // Seems like we didn't find any resource.
+ // Return an empty array just like before.
+ \OCP\Util::writeLog('user_ldap', 'Could not search, because resource is missing.', \OCP\Util::DEBUG);
+ return array();
+ }
+
+ if(!is_null($attr)) {
+ $selection = array();
+ $multiarray = false;
+ if(count($attr) > 1) {
+ $multiarray = true;
+ $i = 0;
+ }
+ foreach($findings as $item) {
+ if(!is_array($item)) {
+ continue;
+ }
+ $item = \OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
+
+ if($multiarray) {
+ foreach($attr as $key) {
+ $key = mb_strtolower($key, 'UTF-8');
+ if(isset($item[$key])) {
+ if($key != 'dn') {
+ $selection[$i][$key] = $this->resemblesDN($key) ? $this->sanitizeDN($item[$key][0]) : $item[$key][0];
+ } else {
+ $selection[$i][$key] = $this->sanitizeDN($item[$key]);
+ }
+ }
+
+ }
+ $i++;
+ } else {
+ //tribute to case insensitivity
+ $key = mb_strtolower($attr[0], 'UTF-8');
+
+ if(isset($item[$key])) {
+ if($this->resemblesDN($key)) {
+ $selection[] = $this->sanitizeDN($item[$key]);
+ } else {
+ $selection[] = $item[$key];
+ }
+ }
+ }
+ }
+ return $selection;
+ }
+ return $findings;
+ }
+
+ public function sanitizeUsername($name) {
+ if($this->connection->ldapIgnoreNamingRules) {
+ return $name;
+ }
+
+ //REPLACEMENTS
+ $name = \OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
+
+ //every remaining unallowed characters will be removed
+ $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
+
+ return $name;
+ }
+
+ /**
+ * @brief combines the input filters with AND
+ * @param $filters array, the filters to connect
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ public function combineFilterWithAnd($filters) {
+ return $this->combineFilter($filters, '&');
+ }
+
+ /**
+ * @brief combines the input filters with AND
+ * @param $filters array, the filters to connect
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ public function combineFilterWithOr($filters) {
+ return $this->combineFilter($filters, '|');
+ }
+
+ /**
+ * @brief combines the input filters with given operator
+ * @param $filters array, the filters to connect
+ * @param $operator either & or |
+ * @returns the combined filter
+ *
+ * Combines Filter arguments with AND
+ */
+ private function combineFilter($filters, $operator) {
+ $combinedFilter = '('.$operator;
+ foreach($filters as $filter) {
+ if($filter[0] != '(') {
+ $filter = '('.$filter.')';
+ }
+ $combinedFilter.=$filter;
+ }
+ $combinedFilter.=')';
+ return $combinedFilter;
+ }
+
+ public function areCredentialsValid($name, $password) {
+ $testConnection = clone $this->connection;
+ $credentials = array(
+ 'ldapAgentName' => $name,
+ 'ldapAgentPassword' => $password
+ );
+ if(!$testConnection->setConfiguration($credentials)) {
+ return false;
+ }
+ return $testConnection->bind();
+ }
+} \ No newline at end of file
diff --git a/apps/user_ldap/lib/connection.php b/apps/user_ldap/lib/connection.php
new file mode 100644
index 00000000000..e54a8e2b241
--- /dev/null
+++ b/apps/user_ldap/lib/connection.php
@@ -0,0 +1,255 @@
+<?php
+
+/**
+ * ownCloud – LDAP Access
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+namespace OCA\user_ldap\lib;
+
+class Connection {
+ private $ldapConnectionRes = null;
+ private $configID;
+ private $configured = false;
+
+ //cached settings
+ protected $config = array(
+ 'ldapHost' => null,
+ 'ldapPort' => null,
+ 'ldapBase' => null,
+ 'ldapBaseUsers' => null,
+ 'ldapBaseGroups' => null,
+ 'ldapAgentName' => null,
+ 'ldapAgentPassword' => null,
+ 'ldapTLS' => null,
+ 'ldapNoCase' => null,
+ 'ldapIgnoreNamingRules' => null,
+ 'ldapUserDisplayName' => null,
+ 'ldapUserFilter' => null,
+ 'ldapGroupFilter' => null,
+ 'ldapGroupDisplayName' => null,
+ 'ldapLoginFilter' => null,
+ 'ldapQuotaAttribute' => null,
+ 'ldapQuotaDefault' => null,
+ 'ldapEmailAttribute' => null,
+ );
+
+ public function __construct($configID = 'user_ldap') {
+ $this->configID = $configID;
+ }
+
+ public function __destruct() {
+ @ldap_unbind($this->ldapConnectionRes);
+ }
+
+ public function __get($name) {
+ if(!$this->configured) {
+ $this->readConfiguration();
+ }
+
+ if(isset($this->config[$name])) {
+ return $this->config[$name];
+ }
+ }
+
+ /**
+ * @brief initializes the LDAP backend
+ * @param $force read the config settings no matter what
+ *
+ * initializes the LDAP backend
+ */
+ public function init($force = false) {
+ $this->readConfiguration($force);
+ $this->establishConnection();
+ }
+
+ /**
+ * Returns the LDAP handler
+ */
+ public function getConnectionResource() {
+ if(!$this->ldapConnectionRes) {
+ $this->init();
+ }
+ if(is_null($this->ldapConnectionRes)) {
+ \OCP\Util::writeLog('user_ldap', 'Connection could not be established', \OCP\Util::ERROR);
+ }
+ return $this->ldapConnectionRes;
+ }
+
+ /**
+ * Caches the general LDAP configuration.
+ */
+ private function readConfiguration($force = false) {
+ \OCP\Util::writeLog('user_ldap','Checking conf state: isConfigured? '.print_r($this->configured, true).' isForce? '.print_r($force, true).' configID? '.print_r($this->configID, true), \OCP\Util::DEBUG);
+ if((!$this->configured || $force) && !is_null($this->configID)) {
+ \OCP\Util::writeLog('user_ldap','Reading the configuration', \OCP\Util::DEBUG);
+ $this->config['ldapHost'] = \OCP\Config::getAppValue($this->configID, 'ldap_host', '');
+ $this->config['ldapPort'] = \OCP\Config::getAppValue($this->configID, 'ldap_port', 389);
+ $this->config['ldapAgentName'] = \OCP\Config::getAppValue($this->configID, 'ldap_dn','');
+ $this->config['ldapAgentPassword'] = base64_decode(\OCP\Config::getAppValue($this->configID, 'ldap_agent_password',''));
+ $this->config['ldapBase'] = \OCP\Config::getAppValue($this->configID, 'ldap_base', '');
+ $this->config['ldapBaseUsers'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_users',$this->config['ldapBase']);
+ $this->config['ldapBaseGroups'] = \OCP\Config::getAppValue($this->configID, 'ldap_base_groups', $this->config['ldapBase']);
+ $this->config['ldapTLS'] = \OCP\Config::getAppValue($this->configID, 'ldap_tls',0);
+ $this->config['ldapNoCase'] = \OCP\Config::getAppValue($this->configID, 'ldap_nocase', 0);
+ $this->config['ldapUserDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_display_name', 'uid'), 'UTF-8');
+ $this->config['ldapUserFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_userlist_filter','objectClass=person');
+ $this->config['ldapGroupFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_filter','(objectClass=posixGroup)');
+ $this->config['ldapLoginFilter'] = \OCP\Config::getAppValue($this->configID, 'ldap_login_filter', '(uid=%uid)');
+ $this->config['ldapGroupDisplayName'] = mb_strtolower(\OCP\Config::getAppValue($this->configID, 'ldap_group_display_name', 'uid'), 'UTF-8');
+ $this->config['ldapQuotaAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_attr', '');
+ $this->config['ldapQuotaDefault'] = \OCP\Config::getAppValue($this->configID, 'ldap_quota_def', '');
+ $this->config['ldapEmailAttribute'] = \OCP\Config::getAppValue($this->configID, 'ldap_email_attr', '');
+ $this->config['ldapGroupMemberAssocAttr'] = \OCP\Config::getAppValue($this->configID, 'ldap_group_member_assoc_attribute', 'uniqueMember');
+ $this->config['ldapIgnoreNamingRules'] = \OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
+
+ $this->configured = $this->validateConfiguration();
+ }
+ }
+
+ /**
+ * @brief set LDAP configuration with values delivered by an array, not read from configuration
+ * @param $config array that holds the config parameters in an associated array
+ * @param &$setParameters optional; array where the set fields will be given to
+ * @return true if config validates, false otherwise. Check with $setParameters for detailed success on single parameters
+ */
+ public function setConfiguration($config, &$setParameters = null) {
+ if(!is_array($config)) {
+ return false;
+ }
+
+ foreach($config as $parameter => $value) {
+ if(isset($this->config[$parameter])) {
+ $this->config[$parameter] = $value;
+ if(is_array($setParameters)) {
+ $setParameters[] = $parameter;
+ }
+ }
+ }
+
+ $this->configured = $this->validateConfiguration();
+
+ return $this->configured;
+ }
+
+ /**
+ * @brief Validates the user specified configuration
+ * @returns true if configuration seems OK, false otherwise
+ */
+ private function validateConfiguration() {
+ //first step: "soft" checks: settings that are not really necessary, but advisable. If left empty, give an info message
+ if(empty($this->config['ldapBaseUsers'])) {
+ \OCP\Util::writeLog('user_ldap', 'Base tree for Users is empty, using Base DN', \OCP\Util::INFO);
+ $this->config['ldapBaseUsers'] = $this->config['ldapBase'];
+ }
+ if(empty($this->config['ldapBaseGroups'])) {
+ \OCP\Util::writeLog('user_ldap', 'Base tree for Groups is empty, using Base DN', \OCP\Util::INFO);
+ $this->config['ldapBaseGroups'] = $this->config['ldapBase'];
+ }
+ if(empty($this->config['ldapGroupFilter']) && empty($this->config['ldapGroupMemberAssocAttr'])) {
+ \OCP\Util::writeLog('user_ldap', 'No group filter is specified, LDAP group feature will not be used.', \OCP\Util::INFO);
+ }
+
+ //second step: critical checks. If left empty or filled wrong, set as unconfigured and give a warning.
+ $configurationOK = true;
+ if(empty($this->config['ldapHost'])) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP host given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapPort'])) {
+ \OCP\Util::writeLog('user_ldap', 'No LDAP Port given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if((empty($this->config['ldapAgentName']) && !empty($this->config['ldapAgentPassword']))
+ || (!empty($this->config['ldapAgentName']) && empty($this->config['ldapAgentPassword']))) {
+ \OCP\Util::writeLog('user_ldap', 'Either no password given for the user agent or a password is given, but no LDAP agent; won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ //TODO: check if ldapAgentName is in DN form
+ if(empty($this->config['ldapBase']) && (empty($this->config['ldapBaseUsers']) && empty($this->config['ldapBaseGroups']))) {
+ \OCP\Util::writeLog('user_ldap', 'No Base DN given, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapUserDisplayName'])) {
+ \OCP\Util::writeLog('user_ldap', 'No user display name attribute specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapGroupDisplayName'])) {
+ \OCP\Util::writeLog('user_ldap', 'No group display name attribute specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(empty($this->config['ldapLoginFilter'])) {
+ \OCP\Util::writeLog('user_ldap', 'No login filter specified, won`t connect.', \OCP\Util::WARN);
+ $configurationOK = false;
+ }
+ if(mb_strpos($this->config['ldapLoginFilter'], '%uid', 0, 'UTF-8') === false) {
+ \OCP\Util::writeLog('user_ldap', 'Login filter does not contain %uid place holder, won`t connect.', \OCP\Util::WARN);
+ \OCP\Util::writeLog('user_ldap', 'Login filter was ' . $this->config['ldapLoginFilter'], \OCP\Util::DEBUG);
+ $configurationOK = false;
+ }
+
+ return $configurationOK;
+ }
+
+ /**
+ * Connects and Binds to LDAP
+ */
+ private function establishConnection() {
+ static $phpLDAPinstalled = true;
+ if(!$phpLDAPinstalled) {
+ return false;
+ }
+ if(!$this->configured) {
+ \OCP\Util::writeLog('user_ldap', 'Configuration is invalid, cannot connect', \OCP\Util::WARN);
+ return false;
+ }
+ if(!$this->ldapConnectionRes) {
+ if(!function_exists('ldap_connect')) {
+ $phpLDAPinstalled = false;
+ \OCP\Util::writeLog('user_ldap', 'function ldap_connect is not available. Make sure that the PHP ldap module is installed.', \OCP\Util::ERROR);
+
+ return false;
+ }
+ $this->ldapConnectionRes = ldap_connect($this->config['ldapHost'], $this->config['ldapPort']);
+ if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
+ if(ldap_set_option($this->ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
+ if($this->config['ldapTLS']) {
+ ldap_start_tls($this->ldapConnectionRes);
+ }
+ }
+ }
+
+ return $this->bind();
+ }
+ }
+
+ /**
+ * Binds to LDAP
+ */
+ public function bind() {
+ $ldapLogin = @ldap_bind($this->getConnectionResource(), $this->config['ldapAgentName'], $this->config['ldapAgentPassword']);
+ if(!$ldapLogin) {
+ \OCP\Util::writeLog('user_ldap', 'Bind failed: ' . ldap_errno($this->ldapConnectionRes) . ': ' . ldap_error($this->ldapConnectionRes), \OCP\Util::ERROR);
+ $this->ldapConnectionRes = null;
+ return false;
+ }
+ return true;
+ }
+
+} \ No newline at end of file
diff --git a/apps/user_ldap/lib_ldap.php b/apps/user_ldap/lib_ldap.php
deleted file mode 100644
index 08b09304d78..00000000000
--- a/apps/user_ldap/lib_ldap.php
+++ /dev/null
@@ -1,721 +0,0 @@
-<?php
-
-/**
- * ownCloud – LDAP lib
- *
- * @author Arthur Schiwon
- * @copyright 2012 Arthur Schiwon blizzz@owncloud.com
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or any later version.
- *
- * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
- *
- * You should have received a copy of the GNU Affero General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-define('LDAP_GROUP_MEMBER_ASSOC_ATTR','uniqueMember');
-define('LDAP_GROUP_DISPLAY_NAME_ATTR','cn');
-
-//needed to unbind, because we use OC_LDAP only statically
-class OC_LDAP_DESTRUCTOR {
- public function __destruct() {
- OC_LDAP::destruct();
- }
-}
-
-class OC_LDAP {
- static protected $ldapConnectionRes = false;
- static protected $configured = false;
-
- //cached settings
- static protected $ldapHost;
- static protected $ldapPort;
- static protected $ldapBase;
- static protected $ldapBaseUsers;
- static protected $ldapBaseGroups;
- static protected $ldapAgentName;
- static protected $ldapAgentPassword;
- static protected $ldapTLS;
- static protected $ldapNoCase;
- static protected $ldapIgnoreNamingRules;
- // user and group settings, that are needed in both backends
- static protected $ldapUserDisplayName;
- static protected $ldapUserFilter;
- static protected $ldapGroupDisplayName;
- static protected $ldapLoginFilter;
-
- static protected $__d;
-
- /**
- * @brief initializes the LDAP backend
- * @param $force read the config settings no matter what
- *
- * initializes the LDAP backend
- */
- static public function init($force = false) {
- if(is_null(self::$__d)) {
- self::$__d = new OC_LDAP_DESTRUCTOR();
- }
- self::readConfiguration($force);
- self::establishConnection();
- }
-
- static public function destruct() {
- @ldap_unbind(self::$ldapConnectionRes);
- }
-
- /**
- * @brief returns a read-only configuration value
- * @param $key the name of the configuration value
- * @returns the value on success, otherwise null
- *
- * returns a read-only configuration values
- *
- * we cannot work with getters, because it is a static class
- */
- static public function conf($key) {
- if(!self::$configured) {
- self::init();
- }
-
- $availableProperties = array(
- 'ldapUserDisplayName',
- 'ldapGroupDisplayName',
- 'ldapLoginFilter'
- );
-
- if(in_array($key, $availableProperties)) {
- return self::$$key;
- }
-
- return null;
- }
-
- /**
- * gives back the database table for the query
- */
- static private function getMapTable($isUser) {
- if($isUser) {
- return '*PREFIX*ldap_user_mapping';
- } else {
- return '*PREFIX*ldap_group_mapping';
- }
- }
-
- /**
- * @brief returns the LDAP DN for the given internal ownCloud name of the group
- * @param $name the ownCloud name in question
- * @returns string with the LDAP DN on success, otherwise false
- *
- * returns the LDAP DN for the given internal ownCloud name of the group
- */
- static public function groupname2dn($name) {
- return self::ocname2dn($name, false);
- }
-
- /**
- * @brief returns the LDAP DN for the given internal ownCloud name of the user
- * @param $name the ownCloud name in question
- * @returns string with the LDAP DN on success, otherwise false
- *
- * returns the LDAP DN for the given internal ownCloud name of the user
- */
- static public function username2dn($name) {
- $dn = self::ocname2dn($name, true);
- if($dn) {
- return $dn;
- } else {
- //fallback: user is not mapped
- self::init();
- $filter = self::combineFilterWithAnd(array(
- self::$ldapUserFilter,
- self::$ldapUserDisplayName . '=' . $name,
- ));
- $result = self::searchUsers($filter, 'dn');
- if(isset($result[0]['dn'])) {
- self::mapUser($result[0], $name);
- return $result[0];
- }
- }
-
- return false;
- }
-
- static private function ocname2dn($name, $isUser) {
- $table = self::getMapTable($isUser);
-
- $query = OCP\DB::prepare('
- SELECT ldap_dn
- FROM '.$table.'
- WHERE owncloud_name = ?
- ');
-
- $record = $query->execute(array($name))->fetchOne();
- return $record;
- }
-
- /**
- * @brief returns the internal ownCloud name for the given LDAP DN of the group
- * @param $dn the dn of the group object
- * @param $ldapname optional, the display name of the object
- * @returns string with with the name to use in ownCloud, false on DN outside of search DN
- *
- * returns the internal ownCloud name for the given LDAP DN of the group
- */
- static public function dn2groupname($dn, $ldapname = null) {
- if(mb_strripos($dn, self::$ldapBaseGroups, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseGroups, 'UTF-8'))) {
- return false;
- }
- return self::dn2ocname($dn, $ldapname, false);
- }
-
- /**
- * @brief returns the internal ownCloud name for the given LDAP DN of the user
- * @param $dn the dn of the user object
- * @param $ldapname optional, the display name of the object
- * @returns string with with the name to use in ownCloud
- *
- * returns the internal ownCloud name for the given LDAP DN of the user, false on DN outside of search DN
- */
- static public function dn2username($dn, $ldapname = null) {
- if(mb_strripos($dn, self::$ldapBaseUsers, 0, 'UTF-8') !== (mb_strlen($dn, 'UTF-8')-mb_strlen(self::$ldapBaseUsers, 'UTF-8'))) {
- return false;
- }
- return self::dn2ocname($dn, $ldapname, true);
- }
-
- static public function dn2ocname($dn, $ldapname = null, $isUser = true) {
- $dn = self::sanitizeDN($dn);
- $table = self::getMapTable($isUser);
- if($isUser) {
- $nameAttribute = self::conf('ldapUserDisplayName');
- } else {
- $nameAttribute = self::conf('ldapGroupDisplayName');
- }
-
- $query = OCP\DB::prepare('
- SELECT owncloud_name
- FROM '.$table.'
- WHERE ldap_dn = ?
- ');
-
- $component = $query->execute(array($dn))->fetchOne();
- if($component) {
- return $component;
- }
-
- if(is_null($ldapname)) {
- $ldapname = self::readAttribute($dn, $nameAttribute);
- $ldapname = $ldapname[0];
- }
- $ldapname = self::sanitizeUsername($ldapname);
-
- //a new user/group! Then let's try to add it. We're shooting into the blue with the user/group name, assuming that in most cases there will not be a conflict. Otherwise an error will occur and we will continue with our second shot.
- if(self::mapComponent($dn, $ldapname, $isUser)) {
- return $ldapname;
- }
-
- //doh! There is a conflict. We need to distinguish between users/groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this object is located.
- $oc_name = self::alternateOwnCloudName($ldapname, $dn);
- if(self::mapComponent($dn, $oc_name, $isUser)) {
- return $oc_name;
- }
-
- //and this of course should never been thrown :)
- throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
- }
-
- /**
- * @brief gives back the user names as they are used ownClod internally
- * @param $ldapGroups an array with the ldap Users result in style of array ( array ('dn' => foo, 'uid' => bar), ... )
- * @returns an array with the user names to use in ownCloud
- *
- * gives back the user names as they are used ownClod internally
- */
- static public function ownCloudUserNames($ldapUsers) {
- return self::ldap2ownCloudNames($ldapUsers, true);
- }
-
- /**
- * @brief gives back the group names as they are used ownClod internally
- * @param $ldapGroups an array with the ldap Groups result in style of array ( array ('dn' => foo, 'cn' => bar), ... )
- * @returns an array with the group names to use in ownCloud
- *
- * gives back the group names as they are used ownClod internally
- */
- static public function ownCloudGroupNames($ldapGroups) {
- return self::ldap2ownCloudNames($ldapGroups, false);
- }
-
- static private function ldap2ownCloudNames($ldapObjects, $isUsers) {
- if($isUsers) {
- $knownObjects = self::mappedUsers();
- $nameAttribute = self::conf('ldapUserDisplayName');
- } else {
- $knownObjects = self::mappedGroups();
- $nameAttribute = self::conf('ldapGroupDisplayName');
- }
- $ownCloudNames = array();
-
- foreach($ldapObjects as $ldapObject) {
- $key = self::recursiveArraySearch($knownObjects, $ldapObject['dn']);
-
- //everything is fine when we know the group
- if($key !== false) {
- $ownCloudNames[] = $knownObjects[$key]['owncloud_name'];
- continue;
- }
-
- //a new group! Then let's try to add it. We're shooting into the blue with the group name, assuming that in most cases there will not be a conflict. But first make sure, that the display name contains only allowed characters.
- $ocname = self::sanitizeUsername($ldapObject[$nameAttribute]);
- if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
- $ownCloudNames[] = $ocname;
- continue;
- }
-
- //doh! There is a conflict. We need to distinguish between groups. Adding indexes is an idea, but not much of a help for the user. The DN is ugly, but for now the only reasonable way. But we transform it to a readable format and remove the first part to only give the path where this entry is located.
- $ocname = self::alternateOwnCloudName($ocname, $ldapObject['dn']);
- if(self::mapComponent($ldapObject['dn'], $ocname, $isUsers)) {
- $ownCloudNames[] = $ocname;
- continue;
- }
-
- //and this of course should never been thrown :)
- throw new Exception('LDAP backend: unexpected collision of DN and ownCloud Name.');
- }
- return $ownCloudNames;
- }
-
- /**
- * @brief creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
- * @param $name the display name of the object
- * @param $dn the dn of the object
- * @returns string with with the name to use in ownCloud
- *
- * creates a hopefully unique name for owncloud based on the display name and the dn of the LDAP object
- */
- static private function alternateOwnCloudName($name, $dn) {
- $ufn = ldap_dn2ufn($dn);
- $name = $name . '@' . trim(OCP\Util::mb_substr_replace($ufn, '', 0, mb_strpos($ufn, ',', 0, 'UTF-8'), 'UTF-8'));
- $name = self::sanitizeUsername($name);
- return $name;
- }
-
- /**
- * @brief retrieves all known groups from the mappings table
- * @returns array with the results
- *
- * retrieves all known groups from the mappings table
- */
- static private function mappedGroups() {
- return self::mappedComponents(false);
- }
-
- /**
- * @brief retrieves all known users from the mappings table
- * @returns array with the results
- *
- * retrieves all known users from the mappings table
- */
- static private function mappedUsers() {
- return self::mappedComponents(true);
- }
-
- static private function mappedComponents($isUsers) {
- $table = self::getMapTable($isUsers);
-
- $query = OCP\DB::prepare('
- SELECT ldap_dn, owncloud_name
- FROM '. $table
- );
-
- return $query->execute()->fetchAll();
- }
-
- /**
- * @brief inserts a new user or group into the mappings table
- * @param $dn the record in question
- * @param $ocname the name to use in ownCloud
- * @param $isUser is it a user or a group?
- * @returns true on success, false otherwise
- *
- * inserts a new user or group into the mappings table
- */
- static private function mapComponent($dn, $ocname, $isUser = true) {
- $table = self::getMapTable($isUser);
- $dn = self::sanitizeDN($dn);
-
- $sqlAdjustment = '';
- $dbtype = OCP\Config::getSystemValue('dbtype');
- if($dbtype == 'mysql') {
- $sqlAdjustment = 'FROM dual';
- }
-
- $insert = OCP\DB::prepare('
- INSERT INTO '.$table.' (ldap_dn, owncloud_name)
- SELECT ?,?
- '.$sqlAdjustment.'
- WHERE NOT EXISTS (
- SELECT 1
- FROM '.$table.'
- WHERE ldap_dn = ?
- OR owncloud_name = ? )
- ');
-
- $res = $insert->execute(array($dn, $ocname, $dn, $ocname));
-
- if(OCP\DB::isError($res)) {
- return false;
- }
-
- $insRows = $res->numRows();
-
- if($insRows == 0) {
- return false;
- }
-
- return true;
- }
-
- static public function fetchListOfUsers($filter, $attr) {
- return self::fetchList(OC_LDAP::searchUsers($filter, $attr), (count($attr) > 1));
- }
-
- static public function fetchListOfGroups($filter, $attr) {
- return self::fetchList(OC_LDAP::searchGroups($filter, $attr), (count($attr) > 1));
- }
-
- static private function fetchList($list, $manyAttributes) {
- if(is_array($list)) {
- if($manyAttributes) {
- return $list;
- } else {
- return array_unique($list, SORT_LOCALE_STRING);
- }
- }
-
- //error cause actually, maybe throw an exception in future.
- return array();
- }
-
- /**
- * @brief reads a given attribute for an LDAP record identified by a DN
- * @param $dn the record in question
- * @param $attr the attribute that shall be retrieved
- * @returns the values in an array on success, false otherwise
- *
- * Reads an attribute from an LDAP entry
- */
- static public function readAttribute($dn, $attr) {
- $cr = self::getConnectionResource();
- $rr = ldap_read($cr, $dn, 'objectClass=*', array($attr));
- $er = ldap_first_entry($cr, $rr);
- //LDAP attributes are not case sensitive
- $result = OCP\Util::mb_array_change_key_case(ldap_get_attributes($cr, $er), MB_CASE_LOWER, 'UTF-8');
- $attr = mb_strtolower($attr, 'UTF-8');
-
- if(isset($result[$attr]) && $result[$attr]['count'] > 0){
- $values = array();
- for($i=0;$i<$result[$attr]['count'];$i++) {
- $values[] = self::resemblesDN($attr) ? self::sanitizeDN($result[$attr][$i]) : $result[$attr][$i];
- }
- return $values;
- }
- return false;
- }
-
- /**
- * @brief executes an LDAP search, optimized for Users
- * @param $filter the LDAP filter for the search
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static public function searchUsers($filter, $attr = null) {
- self::init();
- return self::search($filter, self::$ldapBaseUsers, $attr);
- }
-
- /**
- * @brief executes an LDAP search, optimized for Groups
- * @param $filter the LDAP filter for the search
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static public function searchGroups($filter, $attr = null) {
- self::init();
- return self::search($filter, self::$ldapBaseGroups, $attr);
- }
-
- /**
- * @brief executes an LDAP search
- * @param $filter the LDAP filter for the search
- * @param $base the LDAP subtree that shall be searched
- * @param $attr optional, when a certain attribute shall be filtered out
- * @returns array with the search result
- *
- * Executes an LDAP search
- */
- static private function search($filter, $base, $attr = null) {
- if(!is_null($attr) && !is_array($attr)) {
- $attr = array(mb_strtolower($attr, 'UTF-8'));
- }
-
- // See if we have a resource
- $link_resource = self::getConnectionResource();
- if(is_resource($link_resource)) {
- $sr = ldap_search($link_resource, $base, $filter, $attr);
- $findings = ldap_get_entries($link_resource, $sr );
-
- // if we're here, probably no connection resource is returned.
- // to make ownCloud behave nicely, we simply give back an empty array.
- if(is_null($findings)) {
- return array();
- }
- } else {
- // Seems like we didn't find any resource.
- // Return an empty array just like before.
- return array();
- }
-
- if(!is_null($attr)) {
- $selection = array();
- $multiarray = false;
- if(count($attr) > 1) {
- $multiarray = true;
- $i = 0;
- }
- foreach($findings as $item) {
- if(!is_array($item)) {
- continue;
- }
- $item = OCP\Util::mb_array_change_key_case($item, MB_CASE_LOWER, 'UTF-8');
-
- if($multiarray) {
- foreach($attr as $key) {
- $key = mb_strtolower($key, 'UTF-8');
- if(isset($item[$key])) {
- if($key != 'dn'){
- $selection[$i][$key] = self::resemblesDN($key) ? self::sanitizeDN($item[$key][0]) : $item[$key][0];
- } else {
- $selection[$i][$key] = self::sanitizeDN($item[$key]);
- }
- }
-
- }
- $i++;
- } else {
- //tribute to case insensitivity
- $key = mb_strtolower($attr[0], 'UTF-8');
-
- if(isset($item[$key])) {
- if(self::resemblesDN($key)) {
- $selection[] = self::sanitizeDN($item[$key]);
- } else {
- $selection[] = $item[$key];
- }
- }
- }
-
- }
- return $selection;
- }
-
- return $findings;
- }
-
- static private function resemblesDN($attr) {
- $resemblingAttributes = array(
- 'dn',
- 'uniquemember',
- 'member'
- );
- return in_array($attr, $resemblingAttributes);
- }
-
- static private function sanitizeDN($dn) {
- //OID sometimes gives back DNs with whitespace after the comma a la "uid=foo, cn=bar, dn=..." We need to tackle this!
- $dn = preg_replace('/([^\\\]),(\s+)/u','\1,',$dn);
-
- //make comparisons and everything work
- $dn = mb_strtolower($dn, 'UTF-8');
-
- return $dn;
- }
-
- static private function sanitizeUsername($name) {
- if(self::$ldapIgnoreNamingRules) {
- return $name;
- }
-
- //REPLACEMENTS
- $name = OCP\Util::mb_str_replace(' ', '_', $name, 'UTF-8');
-
- //every remaining unallowed characters will be removed
- $name = preg_replace('/[^a-zA-Z0-9_.@-]/u', '', $name);
-
- return $name;
- }
-
- /**
- * @brief combines the input filters with AND
- * @param $filters array, the filters to connect
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static public function combineFilterWithAnd($filters) {
- return self::combineFilter($filters,'&');
- }
-
- /**
- * @brief combines the input filters with AND
- * @param $filters array, the filters to connect
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static public function combineFilterWithOr($filters) {
- return self::combineFilter($filters,'|');
- }
-
- /**
- * @brief combines the input filters with given operator
- * @param $filters array, the filters to connect
- * @param $operator either & or |
- * @returns the combined filter
- *
- * Combines Filter arguments with AND
- */
- static private function combineFilter($filters, $operator) {
- $combinedFilter = '('.$operator;
- foreach($filters as $filter) {
- if($filter[0] != '(') {
- $filter = '('.$filter.')';
- }
- $combinedFilter.=$filter;
- }
- $combinedFilter.=')';
- return $combinedFilter;
- }
-
- /**
- * Returns the LDAP handler
- */
- static private function getConnectionResource() {
- if(!self::$ldapConnectionRes) {
- self::init();
- }
- if(is_null(self::$ldapConnectionRes)) {
- OCP\Util::writeLog('ldap', 'Connection could not be established', OCP\Util::INFO);
- }
- return self::$ldapConnectionRes;
- }
-
- /**
- * Caches the general LDAP configuration.
- */
- static private function readConfiguration($force = false) {
- if(!self::$configured || $force) {
- self::$ldapHost = OCP\Config::getAppValue('user_ldap', 'ldap_host', '');
- self::$ldapPort = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389);
- self::$ldapAgentName = OCP\Config::getAppValue('user_ldap', 'ldap_dn','');
- self::$ldapAgentPassword = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password',''));
- self::$ldapBase = OCP\Config::getAppValue('user_ldap', 'ldap_base', '');
- self::$ldapBaseUsers = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase);
- self::$ldapBaseGroups = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
- self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0);
- self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0);
- self::$ldapUserDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'), 'UTF-8');
- self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
- self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)');
- self::$ldapGroupDisplayName = mb_strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR), 'UTF-8');
- self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
-
- if(empty(self::$ldapBaseUsers)) {
- OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO);
- self::$ldapBaseUsers = self::$ldapBase;
- }
- if(empty(self::$ldapBaseGroups)) {
- OCP\Util::writeLog('ldap', 'Base for Groups is empty, using Base DN', OCP\Util::INFO);
- self::$ldapBaseGroups = self::$ldapBase;
- }
-
- if(
- !empty(self::$ldapHost)
- && !empty(self::$ldapPort)
- && (
- (!empty(self::$ldapAgentName) && !empty(self::$ldapAgentPassword))
- || ( empty(self::$ldapAgentName) && empty(self::$ldapAgentPassword))
- )
- && !empty(self::$ldapBase)
- && !empty(self::$ldapUserDisplayName)
- )
- {
- self::$configured = true;
- }
- }
- }
-
- /**
- * Connects and Binds to LDAP
- */
- static private function establishConnection() {
- if(!self::$configured) {
- OCP\Util::writeLog('ldap', 'Configuration is invalid, cannot connect', OCP\Util::INFO);
- return false;
- }
- if(!self::$ldapConnectionRes) {
- self::$ldapConnectionRes = ldap_connect(self::$ldapHost, self::$ldapPort);
- if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_PROTOCOL_VERSION, 3)) {
- if(ldap_set_option(self::$ldapConnectionRes, LDAP_OPT_REFERRALS, 0)) {
- if(self::$ldapTLS) {
- ldap_start_tls(self::$ldapConnectionRes);
- }
- }
- }
-
- $ldapLogin = @ldap_bind(self::$ldapConnectionRes, self::$ldapAgentName, self::$ldapAgentPassword );
- if(!$ldapLogin) {
- OCP\Util::writeLog('ldap', 'Bind failed: ' . ldap_errno(self::$ldapConnectionRes) . ': ' . ldap_error(self::$ldapConnectionRes), OCP\Util::ERROR);
- self::$ldapConnectionRes = null;
- return false;
- }
- }
- }
-
- static public function areCredentialsValid($name, $password) {
- return @ldap_bind(self::getConnectionResource(), $name, $password);
- }
-
- /**
- * taken from http://www.php.net/manual/en/function.array-search.php#97645
- * TODO: move somewhere, where its better placed since it is not LDAP specific. OC_Helper maybe?
- */
- static public function recursiveArraySearch($haystack, $needle, $index = null) {
- $aIt = new RecursiveArrayIterator($haystack);
- $it = new RecursiveIteratorIterator($aIt);
-
- while($it->valid()) {
- if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
- return $aIt->key();
- }
-
- $it->next();
- }
-
- return false;
- }
-
- }
diff --git a/apps/user_ldap/tests/group_ldap.php b/apps/user_ldap/tests/group_ldap.php
index 2be6b46fb23..106459580fa 100644
--- a/apps/user_ldap/tests/group_ldap.php
+++ b/apps/user_ldap/tests/group_ldap.php
@@ -26,8 +26,8 @@ class Test_Group_Ldap extends UnitTestCase {
}
function testSingleBackend(){
- OC_Group::useBackend(new OC_GROUP_LDAP());
- $group_ldap = new OC_GROUP_LDAP();
+ OC_Group::useBackend(new OCA\user_ldap\GROUP_LDAP());
+ $group_ldap = new OCA\user_ldap\GROUP_LDAP();
$this->assertIsA(OC_Group::getGroups(),gettype(array()));
$this->assertIsA($group_ldap->getGroups(),gettype(array()));
diff --git a/apps/user_ldap/user_ldap.php b/apps/user_ldap/user_ldap.php
index b51d9a55cc7..a4a8921d08d 100644
--- a/apps/user_ldap/user_ldap.php
+++ b/apps/user_ldap/user_ldap.php
@@ -23,13 +23,9 @@
*
*/
-class OC_USER_LDAP extends OC_User_Backend {
+namespace OCA\user_ldap;
- // cached settings
- protected $ldapUserFilter;
- protected $ldapQuotaAttribute;
- protected $ldapQuotaDefault;
- protected $ldapEmailAttribute;
+class USER_LDAP extends lib\Access implements \OCP\UserInterface {
// will be retrieved from LDAP server
protected $ldap_dc = false;
@@ -37,39 +33,32 @@ class OC_USER_LDAP extends OC_User_Backend {
// cache getUsers()
protected $_users = null;
- public function __construct() {
- $this->ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter', '(objectClass=posixAccount)');
- $this->ldapQuotaAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_quota_attr', '');
- $this->ldapQuotaDefault = OCP\Config::getAppValue('user_ldap', 'ldap_quota_def', '');
- $this->ldapEmailAttribute = OCP\Config::getAppValue('user_ldap', 'ldap_email_attr', '');
- }
-
private function updateQuota($dn) {
$quota = null;
- if(!empty($this->ldapQuotaDefault)) {
- $quota = $this->ldapQuotaDefault;
+ if(!empty($this->connection->ldapQuotaDefault)) {
+ $quota = $this->connection->ldapQuotaDefault;
}
- if(!empty($this->ldapQuotaAttribute)) {
- $aQuota = OC_LDAP::readAttribute($dn, $this->ldapQuotaAttribute);
+ if(!empty($this->connection->ldapQuotaAttribute)) {
+ $aQuota = $this->readAttribute($dn, $this->connection->ldapQuotaAttribute);
if($aQuota && (count($aQuota) > 0)) {
$quota = $aQuota[0];
}
}
if(!is_null($quota)) {
- OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'files', 'quota', OCP\Util::computerFileSize($quota));
+ \OCP\Config::setUserValue($this->dn2username($dn), 'files', 'quota', \OCP\Util::computerFileSize($quota));
}
}
private function updateEmail($dn) {
$email = null;
- if(!empty($this->ldapEmailAttribute)) {
- $aEmail = OC_LDAP::readAttribute($dn, $this->ldapEmailAttribute);
+ if(!empty($this->connection->ldapEmailAttribute)) {
+ $aEmail = $this->readAttribute($dn, $this->connection->ldapEmailAttribute);
if($aEmail && (count($aEmail) > 0)) {
$email = $aEmail[0];
}
- if(!is_null($email)){
- OCP\Config::setUserValue(OC_LDAP::dn2username($dn), 'settings', 'email', $email);
+ if(!is_null($email)) {
+ \OCP\Config::setUserValue($this->dn2username($dn), 'settings', 'email', $email);
}
}
}
@@ -84,15 +73,15 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function checkPassword($uid, $password){
//find out dn of the user name
- $filter = OCP\Util::mb_str_replace('%uid', $uid, OC_LDAP::conf('ldapLoginFilter'), 'UTF-8');
- $ldap_users = OC_LDAP::fetchListOfUsers($filter, 'dn');
+ $filter = \OCP\Util::mb_str_replace('%uid', $uid, $this->connection->ldapLoginFilter, 'UTF-8');
+ $ldap_users = $this->fetchListOfUsers($filter, 'dn');
if(count($ldap_users) < 1) {
return false;
}
$dn = $ldap_users[0];
//are the credentials OK?
- if(!OC_LDAP::areCredentialsValid($dn, $password)) {
+ if(!$this->areCredentialsValid($dn, $password)) {
return false;
}
@@ -101,7 +90,7 @@ class OC_USER_LDAP extends OC_User_Backend {
$this->updateEmail($dn);
//give back the display name
- return OC_LDAP::dn2username($dn);
+ return $this->dn2username($dn);
}
/**
@@ -112,8 +101,8 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function getUsers(){
if(is_null($this->_users)) {
- $ldap_users = OC_LDAP::fetchListOfUsers($this->ldapUserFilter, array(OC_LDAP::conf('ldapUserDisplayName'), 'dn'));
- $this->_users = OC_LDAP::ownCloudUserNames($ldap_users);
+ $ldap_users = $this->fetchListOfUsers($this->connection->ldapUserFilter, array($this->connection->ldapUserDisplayName, 'dn'));
+ $this->_users = $this->ownCloudUserNames($ldap_users);
}
return $this->_users;
}
@@ -125,13 +114,13 @@ class OC_USER_LDAP extends OC_User_Backend {
*/
public function userExists($uid){
//getting dn, if false the user does not exist. If dn, he may be mapped only, requires more checking.
- $dn = OC_LDAP::username2dn($uid);
+ $dn = $this->username2dn($uid);
if(!$dn) {
return false;
}
//if user really still exists, we will be able to read his cn
- $cn = OC_LDAP::readAttribute($dn, 'cn');
+ $cn = $this->readAttribute($dn, 'cn');
if(!$cn || empty($cn)) {
return false;
}
@@ -139,4 +128,27 @@ class OC_USER_LDAP extends OC_User_Backend {
return true;
}
+ /**
+ * @brief delete a user
+ * @param $uid The username of the user to delete
+ * @returns true/false
+ *
+ * Deletes a user
+ */
+ public function deleteUser($uid) {
+ return false;
+ }
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions) {
+ return (bool)(OC_USER_BACKEND_CHECK_PASSWORD & $actions);
+ }
+
} \ No newline at end of file
diff --git a/apps/user_migrate/templates/settings.php b/apps/user_migrate/templates/settings.php
index 1718abe9e0f..bce5fb2d7ca 100644
--- a/apps/user_migrate/templates/settings.php
+++ b/apps/user_migrate/templates/settings.php
@@ -12,7 +12,7 @@
<?php } ?>
<legend><strong><?php echo $l->t('Import user account');?></strong></legend>
</p>
- <p><input type="file" id="owncloud_import" name="owncloud_import" style="width:180px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
+ <p><input type="file" id="owncloud_import" name="owncloud_import" style="width:280px;"><label for="owncloud_import"> <?php echo $l->t('ownCloud User Zip');?></label>
</p>
<input type="submit" name="user_import" value="<?php echo $l->t('Import'); ?>" />
</fieldset>
diff --git a/apps/user_openid/user.php b/apps/user_openid/user.php
index d25b95259e0..88571ba618e 100644
--- a/apps/user_openid/user.php
+++ b/apps/user_openid/user.php
@@ -44,4 +44,4 @@ if(!OCP\User::userExists($USERNAME)){
}
$IDENTITY=OCP\Util::linkToAbsolute( "user_openid", "user.php" ).'/'.$USERNAME;
-require_once 'phpmyid.php';
+require_once 'openid/phpmyid.php';
diff --git a/apps/user_openid/user_openid.php b/apps/user_openid/user_openid.php
index 70b193a30b1..19f2f719b06 100644
--- a/apps/user_openid/user_openid.php
+++ b/apps/user_openid/user_openid.php
@@ -21,7 +21,7 @@
*
*/
-require_once('class.openid.v3.php');
+require_once('openid/class.openid.v3.php');
/**
* Class for user OpenId backend
diff --git a/core/ajax/appconfig.php b/core/ajax/appconfig.php
index f815d710631..84e0710c74a 100644
--- a/core/ajax/appconfig.php
+++ b/core/ajax/appconfig.php
@@ -6,7 +6,8 @@
*/
require_once ("../../lib/base.php");
-OC_JSON::checkLoggedIn();
+OC_Util::checkAdminUser();
+
$action=isset($_POST['action'])?$_POST['action']:$_GET['action'];
$result=false;
switch($action){
diff --git a/core/ajax/userlist.php b/core/ajax/userlist.php
deleted file mode 100644
index 85ca004ae66..00000000000
--- a/core/ajax/userlist.php
+++ /dev/null
@@ -1,46 +0,0 @@
-<?php
-
-/**
-* ownCloud - ajax user list
-*
-* @author Hans Bakker
-* @copyright 2011 hansmbakker+kde@gmail.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-$RUNTIME_NOAPPS = TRUE; //no apps, yet
-require_once('../../lib/base.php');
-
-if(!OC_User::isLoggedIn()){
- if(!isset($_SERVER['PHP_AUTH_USER'])){
- header('WWW-Authenticate: Basic realm="ownCloud Server"');
- header('HTTP/1.0 401 Unauthorized');
- echo 'Valid credentials must be supplied';
- exit();
- } else {
- if(!OC_User::checkPassword($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])){
- exit();
- }
- }
-}
-
-$users = array();
-
-foreach( OC_User::getUsers() as $i ){
- $users[] = array( "username" => $i, "groups" => join( ", ", OC_Group::getUserGroups( $i ) ));
-}
-
-OC_JSON::encodedPrint($users);
diff --git a/core/ajax/validateuser.php b/core/ajax/validateuser.php
deleted file mode 100644
index 78ec451fac2..00000000000
--- a/core/ajax/validateuser.php
+++ /dev/null
@@ -1,38 +0,0 @@
-<?php
-
-/**
-* ownCloud
-*
-* @author Hans Bakker
-* @copyright 2011 Hans Bakker hansmbakker+kde@gmail.com
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-$RUNTIME_NOAPPS = TRUE; //no apps, yet
-require_once('../../lib/base.php');
-
-if(!isset($_SERVER['PHP_AUTH_USER'])){
- header('WWW-Authenticate: Basic realm="ownCloud Server"');
- header('HTTP/1.0 401 Unauthorized');
- echo 'Valid credentials must be supplied';
- exit();
-} else {
- if(OC_User::checkPassword($_SERVER["PHP_AUTH_USER"], $_SERVER["PHP_AUTH_PW"])){
- OC_JSON::encodedPrint(array("username" => $_SERVER["PHP_AUTH_USER"], "user_valid" => "true"));
- } else {
- OC_JSON::encodedPrint(array("username" => $_SERVER["PHP_AUTH_USER"], "user_valid" => "false"));
- }
-}
diff --git a/core/js/eventsource.js b/core/js/eventsource.js
index 08259e02cae..e3ad7e3a671 100644
--- a/core/js/eventsource.js
+++ b/core/js/eventsource.js
@@ -40,6 +40,7 @@ OC.EventSource=function(src,data){
dataStr+=name+'='+encodeURIComponent(data[name])+'&';
}
}
+ dataStr+='requesttoken='+OC.EventSource.requesttoken;
if(!this.useFallBack && typeof EventSource !='undefined'){
this.source=new EventSource(src+'?'+dataStr);
this.source.onmessage=function(e){
diff --git a/core/l10n/vi.php b/core/l10n/vi.php
new file mode 100644
index 00000000000..b0b750303aa
--- /dev/null
+++ b/core/l10n/vi.php
@@ -0,0 +1,64 @@
+<?php $TRANSLATIONS = array(
+"Application name not provided." => "Tên ứng dụng không tồn tại",
+"No category to add?" => "Không có danh mục được thêm?",
+"This category already exists: " => "Danh mục này đã được tạo :",
+"ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=" => "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+=",
+"January" => "Tháng 1",
+"February" => "Tháng 2",
+"March" => "Tháng 3",
+"April" => "Tháng 4",
+"May" => "Tháng 5",
+"June" => "Tháng 6",
+"July" => "Tháng 7",
+"August" => "Tháng 8",
+"September" => "Tháng 9",
+"October" => "Tháng 10",
+"November" => "Tháng 11",
+"December" => "Tháng 12",
+"Cancel" => "Hủy",
+"No" => "No",
+"Yes" => "Yes",
+"Ok" => "Ok",
+"No categories selected for deletion." => "Không có thể loại nào được chọn để xóa.",
+"Error" => "Lỗi",
+"ownCloud password reset" => "Khôi phục mật khẩu Owncloud ",
+"Use the following link to reset your password: {link}" => "Dùng đường dẫn sau để khôi phục lại mật khẩu : {link}",
+"You will receive a link to reset your password via Email." => "Vui lòng kiểm tra Email để khôi phục lại mật khẩu.",
+"Requested" => "Yêu cầu",
+"Login failed!" => "Bạn đã nhập sai mật khẩu hay tên người dùng !",
+"Username" => "Tên người dùng",
+"Request reset" => "Yêu cầu thiết lập lại ",
+"Your password was reset" => "Mật khẩu của bạn đã được khôi phục",
+"To login page" => "Trang đăng nhập",
+"New password" => "Mật khẩu mới",
+"Reset password" => "Khôi phục mật khẩu",
+"Personal" => "Cá nhân",
+"Users" => "Người sử dụng",
+"Apps" => "Ứng dụng",
+"Admin" => "Quản trị",
+"Help" => "Giúp đỡ",
+"Access forbidden" => "Truy cập bị cấm ",
+"Cloud not found" => "Không tìm thấy Clound",
+"Edit categories" => "Sửa thể loại",
+"Add" => "Thêm",
+"Create an <strong>admin account</strong>" => "Tạo một <strong>tài khoản quản trị</strong>",
+"Password" => "Mật khẩu",
+"Advanced" => "Nâng cao",
+"Data folder" => "Thư mục dữ liệu",
+"Configure the database" => "Cấu hình Cơ Sở Dữ Liệu",
+"will be used" => "được sử dụng",
+"Database user" => "Người dùng cơ sở dữ liệu",
+"Database password" => "Mật khẩu cơ sở dữ liệu",
+"Database name" => "Tên cơ sở dữ liệu",
+"Database host" => "Database host",
+"Finish setup" => "Cài đặt hoàn tất",
+"web services under your control" => "các dịch vụ web dưới sự kiểm soát của bạn",
+"Log out" => "Đăng xuất",
+"Settings" => "Cài đặt",
+"Lost your password?" => "Bạn quên mật khẩu ?",
+"remember" => "Nhớ",
+"Log in" => "Đăng nhập",
+"You are logged out." => "Bạn đã đăng xuất.",
+"prev" => "Lùi lại",
+"next" => "Kế tiếp"
+);
diff --git a/core/templates/layout.user.php b/core/templates/layout.user.php
index 7e98fdedc2d..dc303ffc1a7 100644
--- a/core/templates/layout.user.php
+++ b/core/templates/layout.user.php
@@ -33,6 +33,7 @@
<script type="text/javascript">
$(function() {
requesttoken = '<?php echo $_['requesttoken']; ?>';
+ OC.EventSource.requesttoken=requesttoken;
$(document).bind('ajaxSend', function(elm, xhr, s){
if(requesttoken) {
xhr.setRequestHeader('requesttoken', requesttoken);
diff --git a/l10n/ar_SA/calendar.po b/l10n/ar_SA/calendar.po
new file mode 100644
index 00000000000..32a7e56e62d
--- /dev/null
+++ b/l10n/ar_SA/calendar.po
@@ -0,0 +1,814 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
+msgid "No calendars found."
+msgstr ""
+
+#: ajax/categories/rescan.php:37
+msgid "No events found."
+msgstr ""
+
+#: ajax/event/edit.form.php:20
+msgid "Wrong calendar"
+msgstr ""
+
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr ""
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
+#: ajax/settings/guesstimezone.php:25
+msgid "New Timezone:"
+msgstr ""
+
+#: ajax/settings/settimezone.php:23
+msgid "Timezone changed"
+msgstr ""
+
+#: ajax/settings/settimezone.php:25
+msgid "Invalid request"
+msgstr ""
+
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
+#: templates/settings.php:12
+msgid "Calendar"
+msgstr ""
+
+#: js/calendar.js:828
+msgid "ddd"
+msgstr ""
+
+#: js/calendar.js:829
+msgid "ddd M/d"
+msgstr ""
+
+#: js/calendar.js:830
+msgid "dddd M/d"
+msgstr ""
+
+#: js/calendar.js:833
+msgid "MMMM yyyy"
+msgstr ""
+
+#: js/calendar.js:835
+msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
+msgstr ""
+
+#: js/calendar.js:837
+msgid "dddd, MMM d, yyyy"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:122
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:129
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:130
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:131
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:132
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:133
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Questions"
+msgstr ""
+
+#: lib/app.php:135
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr ""
+
+#: lib/app.php:359 lib/app.php:399
+msgid "unnamed"
+msgstr ""
+
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr ""
+
+#: lib/object.php:372
+msgid "Does not repeat"
+msgstr ""
+
+#: lib/object.php:373
+msgid "Daily"
+msgstr ""
+
+#: lib/object.php:374
+msgid "Weekly"
+msgstr ""
+
+#: lib/object.php:375
+msgid "Every Weekday"
+msgstr ""
+
+#: lib/object.php:376
+msgid "Bi-Weekly"
+msgstr ""
+
+#: lib/object.php:377
+msgid "Monthly"
+msgstr ""
+
+#: lib/object.php:378
+msgid "Yearly"
+msgstr ""
+
+#: lib/object.php:388
+msgid "never"
+msgstr ""
+
+#: lib/object.php:389
+msgid "by occurrences"
+msgstr ""
+
+#: lib/object.php:390
+msgid "by date"
+msgstr ""
+
+#: lib/object.php:400
+msgid "by monthday"
+msgstr ""
+
+#: lib/object.php:401
+msgid "by weekday"
+msgstr ""
+
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
+msgid "Monday"
+msgstr ""
+
+#: lib/object.php:412 templates/calendar.php:5
+msgid "Tuesday"
+msgstr ""
+
+#: lib/object.php:413 templates/calendar.php:5
+msgid "Wednesday"
+msgstr ""
+
+#: lib/object.php:414 templates/calendar.php:5
+msgid "Thursday"
+msgstr ""
+
+#: lib/object.php:415 templates/calendar.php:5
+msgid "Friday"
+msgstr ""
+
+#: lib/object.php:416 templates/calendar.php:5
+msgid "Saturday"
+msgstr ""
+
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
+msgid "Sunday"
+msgstr ""
+
+#: lib/object.php:427
+msgid "events week of month"
+msgstr ""
+
+#: lib/object.php:428
+msgid "first"
+msgstr ""
+
+#: lib/object.php:429
+msgid "second"
+msgstr ""
+
+#: lib/object.php:430
+msgid "third"
+msgstr ""
+
+#: lib/object.php:431
+msgid "fourth"
+msgstr ""
+
+#: lib/object.php:432
+msgid "fifth"
+msgstr ""
+
+#: lib/object.php:433
+msgid "last"
+msgstr ""
+
+#: lib/object.php:467 templates/calendar.php:7
+msgid "January"
+msgstr ""
+
+#: lib/object.php:468 templates/calendar.php:7
+msgid "February"
+msgstr ""
+
+#: lib/object.php:469 templates/calendar.php:7
+msgid "March"
+msgstr ""
+
+#: lib/object.php:470 templates/calendar.php:7
+msgid "April"
+msgstr ""
+
+#: lib/object.php:471 templates/calendar.php:7
+msgid "May"
+msgstr ""
+
+#: lib/object.php:472 templates/calendar.php:7
+msgid "June"
+msgstr ""
+
+#: lib/object.php:473 templates/calendar.php:7
+msgid "July"
+msgstr ""
+
+#: lib/object.php:474 templates/calendar.php:7
+msgid "August"
+msgstr ""
+
+#: lib/object.php:475 templates/calendar.php:7
+msgid "September"
+msgstr ""
+
+#: lib/object.php:476 templates/calendar.php:7
+msgid "October"
+msgstr ""
+
+#: lib/object.php:477 templates/calendar.php:7
+msgid "November"
+msgstr ""
+
+#: lib/object.php:478 templates/calendar.php:7
+msgid "December"
+msgstr ""
+
+#: lib/object.php:488
+msgid "by events date"
+msgstr ""
+
+#: lib/object.php:489
+msgid "by yearday(s)"
+msgstr ""
+
+#: lib/object.php:490
+msgid "by weeknumber(s)"
+msgstr ""
+
+#: lib/object.php:491
+msgid "by day and month"
+msgstr ""
+
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
+msgid "Date"
+msgstr ""
+
+#: lib/search.php:43
+msgid "Cal."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr ""
+
+#: templates/calendar.php:11
+msgid "All day"
+msgstr ""
+
+#: templates/calendar.php:13
+msgid "Missing fields"
+msgstr ""
+
+#: templates/calendar.php:14 templates/part.eventform.php:19
+#: templates/part.showevent.php:11
+msgid "Title"
+msgstr ""
+
+#: templates/calendar.php:16
+msgid "From Date"
+msgstr ""
+
+#: templates/calendar.php:17
+msgid "From Time"
+msgstr ""
+
+#: templates/calendar.php:18
+msgid "To Date"
+msgstr ""
+
+#: templates/calendar.php:19
+msgid "To Time"
+msgstr ""
+
+#: templates/calendar.php:20
+msgid "The event ends before it starts"
+msgstr ""
+
+#: templates/calendar.php:21
+msgid "There was a database fail"
+msgstr ""
+
+#: templates/calendar.php:38
+msgid "Week"
+msgstr ""
+
+#: templates/calendar.php:39
+msgid "Month"
+msgstr ""
+
+#: templates/calendar.php:40
+msgid "List"
+msgstr ""
+
+#: templates/calendar.php:44
+msgid "Today"
+msgstr ""
+
+#: templates/calendar.php:45
+msgid "Calendars"
+msgstr ""
+
+#: templates/calendar.php:59
+msgid "There was a fail, while parsing the file."
+msgstr ""
+
+#: templates/part.choosecalendar.php:1
+msgid "Choose active calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:2
+msgid "Your calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:27
+#: templates/part.choosecalendar.rowfields.php:11
+msgid "CalDav Link"
+msgstr ""
+
+#: templates/part.choosecalendar.php:31
+msgid "Shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:48
+msgid "No shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:8
+msgid "Share Calendar"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:14
+msgid "Download"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:17
+msgid "Edit"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:20
+#: templates/part.editevent.php:9
+msgid "Delete"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.shared.php:4
+msgid "shared with you by"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "New calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "Edit calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editcalendar.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editcalendar.php:29
+msgid "Calendar color"
+msgstr ""
+
+#: templates/part.editcalendar.php:42
+msgid "Save"
+msgstr ""
+
+#: templates/part.editcalendar.php:42 templates/part.editevent.php:8
+#: templates/part.newevent.php:6
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editcalendar.php:43
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.editevent.php:1
+msgid "Edit an event"
+msgstr ""
+
+#: templates/part.editevent.php:10
+msgid "Export"
+msgstr ""
+
+#: templates/part.eventform.php:8 templates/part.showevent.php:3
+msgid "Eventinfo"
+msgstr ""
+
+#: templates/part.eventform.php:9 templates/part.showevent.php:4
+msgid "Repeating"
+msgstr ""
+
+#: templates/part.eventform.php:10 templates/part.showevent.php:5
+msgid "Alarm"
+msgstr ""
+
+#: templates/part.eventform.php:11 templates/part.showevent.php:6
+msgid "Attendees"
+msgstr ""
+
+#: templates/part.eventform.php:13
+msgid "Share"
+msgstr ""
+
+#: templates/part.eventform.php:21
+msgid "Title of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:27 templates/part.showevent.php:19
+msgid "Category"
+msgstr ""
+
+#: templates/part.eventform.php:29
+msgid "Separate categories with commas"
+msgstr ""
+
+#: templates/part.eventform.php:30
+msgid "Edit categories"
+msgstr ""
+
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
+msgid "All Day Event"
+msgstr ""
+
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
+msgid "From"
+msgstr ""
+
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
+msgid "To"
+msgstr ""
+
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
+msgid "Advanced options"
+msgstr ""
+
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
+msgid "Location"
+msgstr ""
+
+#: templates/part.eventform.php:83
+msgid "Location of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
+msgid "Description"
+msgstr ""
+
+#: templates/part.eventform.php:91
+msgid "Description of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
+msgid "Repeat"
+msgstr ""
+
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
+msgid "Advanced"
+msgstr ""
+
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
+msgid "Select weekdays"
+msgstr ""
+
+#: templates/part.eventform.php:164 templates/part.eventform.php:177
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
+msgid "Select days"
+msgstr ""
+
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
+msgid "and the events day of year."
+msgstr ""
+
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
+msgid "and the events day of month."
+msgstr ""
+
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
+msgid "Select months"
+msgstr ""
+
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
+msgid "Select weeks"
+msgstr ""
+
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
+msgid "and the events week of year."
+msgstr ""
+
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
+msgid "Interval"
+msgstr ""
+
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
+msgid "End"
+msgstr ""
+
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
+msgid "occurrences"
+msgstr ""
+
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr ""
+
+#: templates/part.import.php:17
+msgid "Import a calendar file"
+msgstr ""
+
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr ""
+
+#: templates/part.import.php:36
+msgid "Name of new calendar"
+msgstr ""
+
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr ""
+
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr ""
+
+#: templates/part.import.php:47
+msgid "Import"
+msgstr ""
+
+#: templates/part.import.php:56
+msgid "Close Dialog"
+msgstr ""
+
+#: templates/part.newevent.php:1
+msgid "Create a new event"
+msgstr ""
+
+#: templates/part.showevent.php:1
+msgid "View an event"
+msgstr ""
+
+#: templates/part.showevent.php:23
+msgid "No categories selected"
+msgstr ""
+
+#: templates/part.showevent.php:37
+msgid "of"
+msgstr ""
+
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
+msgid "at"
+msgstr ""
+
+#: templates/settings.php:14
+msgid "Timezone"
+msgstr ""
+
+#: templates/settings.php:31
+msgid "Check always for changes of the timezone"
+msgstr ""
+
+#: templates/settings.php:33
+msgid "Timeformat"
+msgstr ""
+
+#: templates/settings.php:35
+msgid "24h"
+msgstr ""
+
+#: templates/settings.php:36
+msgid "12h"
+msgstr ""
+
+#: templates/settings.php:40
+msgid "First day of the week"
+msgstr ""
+
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr ""
+
+#: templates/share.dropdown.php:20
+msgid "Users"
+msgstr ""
+
+#: templates/share.dropdown.php:21
+msgid "select users"
+msgstr ""
+
+#: templates/share.dropdown.php:36 templates/share.dropdown.php:62
+msgid "Editable"
+msgstr ""
+
+#: templates/share.dropdown.php:48
+msgid "Groups"
+msgstr ""
+
+#: templates/share.dropdown.php:49
+msgid "select groups"
+msgstr ""
+
+#: templates/share.dropdown.php:75
+msgid "make public"
+msgstr ""
diff --git a/l10n/ar_SA/contacts.po b/l10n/ar_SA/contacts.po
new file mode 100644
index 00000000000..16f62d246d3
--- /dev/null
+++ b/l10n/ar_SA/contacts.po
@@ -0,0 +1,871 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
+msgid "Error (de)activating addressbook."
+msgstr ""
+
+#: ajax/addcontact.php:47
+msgid "There was an error adding the contact."
+msgstr ""
+
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr ""
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr ""
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr ""
+
+#: ajax/addproperty.php:56
+msgid "Cannot add empty property."
+msgstr ""
+
+#: ajax/addproperty.php:67
+msgid "At least one of the address fields has to be filled out."
+msgstr ""
+
+#: ajax/addproperty.php:76
+msgid "Trying to add duplicate property: "
+msgstr ""
+
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:17
+msgid "No ID provided"
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:34
+msgid "Error setting checksum."
+msgstr ""
+
+#: ajax/categories/delete.php:19
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: ajax/categories/delete.php:26
+msgid "No address books found."
+msgstr ""
+
+#: ajax/categories/delete.php:34
+msgid "No contacts found."
+msgstr ""
+
+#: ajax/contactdetails.php:31
+msgid "Missing ID"
+msgstr ""
+
+#: ajax/contactdetails.php:36
+msgid "Error parsing VCard for ID: \""
+msgstr ""
+
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
+#: ajax/uploadphoto.php:68
+msgid "No contact ID was submitted."
+msgstr ""
+
+#: ajax/currentphoto.php:36
+msgid "Error reading contact photo."
+msgstr ""
+
+#: ajax/currentphoto.php:48
+msgid "Error saving temporary file."
+msgstr ""
+
+#: ajax/currentphoto.php:51
+msgid "The loading photo is not valid."
+msgstr ""
+
+#: ajax/deleteproperty.php:36
+msgid "Information about vCard is incorrect. Please reload the page."
+msgstr ""
+
+#: ajax/deleteproperty.php:43
+msgid "Error deleting contact property."
+msgstr ""
+
+#: ajax/editname.php:31
+msgid "Contact ID is missing."
+msgstr ""
+
+#: ajax/oc_photo.php:32
+msgid "No photo path was submitted."
+msgstr ""
+
+#: ajax/oc_photo.php:39
+msgid "File doesn't exist:"
+msgstr ""
+
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
+msgid "Error loading image."
+msgstr ""
+
+#: ajax/savecrop.php:67
+msgid "Error getting contact object."
+msgstr ""
+
+#: ajax/savecrop.php:76
+msgid "Error getting PHOTO property."
+msgstr ""
+
+#: ajax/savecrop.php:93
+msgid "Error saving contact."
+msgstr ""
+
+#: ajax/savecrop.php:103
+msgid "Error resizing image"
+msgstr ""
+
+#: ajax/savecrop.php:106
+msgid "Error cropping image"
+msgstr ""
+
+#: ajax/savecrop.php:109
+msgid "Error creating temporary image"
+msgstr ""
+
+#: ajax/savecrop.php:112
+msgid "Error finding image: "
+msgstr ""
+
+#: ajax/saveproperty.php:40
+msgid "checksum is not set."
+msgstr ""
+
+#: ajax/saveproperty.php:59
+msgid "Information about vCard is incorrect. Please reload the page: "
+msgstr ""
+
+#: ajax/saveproperty.php:64
+msgid "Something went FUBAR. "
+msgstr ""
+
+#: ajax/saveproperty.php:133
+msgid "Error updating contact property."
+msgstr ""
+
+#: ajax/updateaddressbook.php:21
+msgid "Cannot update addressbook with an empty name."
+msgstr ""
+
+#: ajax/updateaddressbook.php:25
+msgid "Error updating addressbook."
+msgstr ""
+
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
+msgid "Error uploading contacts to storage."
+msgstr ""
+
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
+msgid "Couldn't save temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
+msgid "Couldn't load temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:71
+msgid "No file was uploaded. Unknown error"
+msgstr ""
+
+#: appinfo/app.php:19 templates/settings.php:3
+msgid "Contacts"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Sorry, this functionality has not been implemented yet"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Not implemented"
+msgstr ""
+
+#: js/contacts.js:58
+msgid "Couldn't get a valid address."
+msgstr ""
+
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
+msgid "Error"
+msgstr ""
+
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New Contact"
+msgstr ""
+
+#: js/contacts.js:691
+msgid "This property has to be non-empty."
+msgstr ""
+
+#: js/contacts.js:717
+msgid "Couldn't serialize elements."
+msgstr ""
+
+#: js/contacts.js:826 js/contacts.js:844
+msgid ""
+"'deleteProperty' called without type argument. Please report at "
+"bugs.owncloud.org"
+msgstr ""
+
+#: js/contacts.js:860
+msgid "Edit name"
+msgstr ""
+
+#: js/contacts.js:1141
+msgid "No files selected for upload."
+msgstr ""
+
+#: js/contacts.js:1149
+msgid ""
+"The file you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: js/contacts.js:1314 js/contacts.js:1348
+msgid "Select type"
+msgstr ""
+
+#: js/loader.js:49
+msgid "Result: "
+msgstr ""
+
+#: js/loader.js:49
+msgid " imported, "
+msgstr ""
+
+#: js/loader.js:49
+msgid " failed."
+msgstr ""
+
+#: lib/app.php:29
+msgid "Addressbook not found."
+msgstr ""
+
+#: lib/app.php:33
+msgid "This is not your addressbook."
+msgstr ""
+
+#: lib/app.php:44
+msgid "Contact could not be found."
+msgstr ""
+
+#: lib/app.php:100 templates/part.contact.php:116
+msgid "Address"
+msgstr ""
+
+#: lib/app.php:101
+msgid "Telephone"
+msgstr ""
+
+#: lib/app.php:102 templates/part.contact.php:115
+msgid "Email"
+msgstr ""
+
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
+msgid "Organization"
+msgstr ""
+
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
+msgid "Home"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Mobile"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Text"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Voice"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Message"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Fax"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Video"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Pager"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Internet"
+msgstr ""
+
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:170
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:171
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:172
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:179
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr ""
+
+#: lib/hooks.php:102
+msgid "{name}'s Birthday"
+msgstr ""
+
+#: templates/index.php:15
+msgid "Add Contact"
+msgstr ""
+
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr ""
+
+#: templates/index.php:20
+msgid "Addressbooks"
+msgstr ""
+
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr ""
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr ""
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr ""
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr ""
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr ""
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr ""
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr ""
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr ""
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr ""
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:1
+msgid "Configure Address Books"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:16
+msgid "New Address Book"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:21
+#: templates/part.chooseaddressbook.rowfields.php:8
+msgid "CardDav Link"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:11
+msgid "Download"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:14
+msgid "Edit"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:17
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
+msgid "Delete"
+msgstr ""
+
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
+msgstr ""
+
+#: templates/part.contact.php:18
+msgid "Delete current photo"
+msgstr ""
+
+#: templates/part.contact.php:19
+msgid "Edit current photo"
+msgstr ""
+
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr ""
+
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr ""
+
+#: templates/part.contact.php:34
+msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
+msgstr ""
+
+#: templates/part.contact.php:35
+msgid "Edit name details"
+msgstr ""
+
+#: templates/part.contact.php:40 templates/part.contact.php:112
+msgid "Nickname"
+msgstr ""
+
+#: templates/part.contact.php:41
+msgid "Enter nickname"
+msgstr ""
+
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr ""
+
+#: templates/part.contact.php:45
+msgid "dd-mm-yyyy"
+msgstr ""
+
+#: templates/part.contact.php:46 templates/part.contact.php:119
+msgid "Groups"
+msgstr ""
+
+#: templates/part.contact.php:48
+msgid "Separate groups with commas"
+msgstr ""
+
+#: templates/part.contact.php:49
+msgid "Edit groups"
+msgstr ""
+
+#: templates/part.contact.php:62 templates/part.contact.php:76
+msgid "Preferred"
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Please specify a valid email address."
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Enter email address"
+msgstr ""
+
+#: templates/part.contact.php:67
+msgid "Mail to address"
+msgstr ""
+
+#: templates/part.contact.php:68
+msgid "Delete email address"
+msgstr ""
+
+#: templates/part.contact.php:77
+msgid "Enter phone number"
+msgstr ""
+
+#: templates/part.contact.php:81
+msgid "Delete phone number"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "View on map"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "Edit address details"
+msgstr ""
+
+#: templates/part.contact.php:102
+msgid "Add notes here."
+msgstr ""
+
+#: templates/part.contact.php:109
+msgid "Add field"
+msgstr ""
+
+#: templates/part.contact.php:114
+msgid "Phone"
+msgstr ""
+
+#: templates/part.contact.php:117
+msgid "Note"
+msgstr ""
+
+#: templates/part.contact.php:122
+msgid "Download contact"
+msgstr ""
+
+#: templates/part.contact.php:123
+msgid "Delete contact"
+msgstr ""
+
+#: templates/part.cropphoto.php:65
+msgid "The temporary image has been removed from cache."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:6
+msgid "Edit address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:10
+msgid "Type"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
+msgid "PO Box"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:30
+msgid "Extended"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
+msgid "City"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:42
+msgid "Region"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:48
+msgid "Zipcode"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
+msgid "Country"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:16
+msgid "Addressbook"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:23
+msgid "Hon. prefixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:27
+msgid "Miss"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:28
+msgid "Ms"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:29
+msgid "Mr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:30
+msgid "Sir"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:31
+msgid "Mrs"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:32
+msgid "Dr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:35
+msgid "Given name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:37
+msgid "Additional names"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:39
+msgid "Family name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:41
+msgid "Hon. suffixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:45
+msgid "J.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:46
+msgid "M.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:47
+msgid "D.O."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:48
+msgid "D.C."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:49
+msgid "Ph.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:50
+msgid "Esq."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:51
+msgid "Jr."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:52
+msgid "Sn."
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "New Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "Edit Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editaddressbook.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Save"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editaddressbook.php:30
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.import.php:1
+msgid "Import a contacts file"
+msgstr ""
+
+#: templates/part.import.php:6
+msgid "Please choose the addressbook"
+msgstr ""
+
+#: templates/part.import.php:10
+msgid "create a new addressbook"
+msgstr ""
+
+#: templates/part.import.php:15
+msgid "Name of new addressbook"
+msgstr ""
+
+#: templates/part.import.php:20
+msgid "Importing contacts"
+msgstr ""
+
+#: templates/part.no_contacts.php:2
+msgid "You have no contacts in your addressbook."
+msgstr ""
+
+#: templates/part.no_contacts.php:4
+msgid "Add contact"
+msgstr ""
+
+#: templates/part.no_contacts.php:5
+msgid "Configure addressbooks"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "CardDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:6
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:8
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr ""
diff --git a/l10n/ar_SA/core.po b/l10n/ar_SA/core.po
new file mode 100644
index 00000000000..5c1cf5518c0
--- /dev/null
+++ b/l10n/ar_SA/core.po
@@ -0,0 +1,268 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:28+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/vcategories/add.php:23 ajax/vcategories/delete.php:23
+msgid "Application name not provided."
+msgstr ""
+
+#: ajax/vcategories/add.php:29
+msgid "No category to add?"
+msgstr ""
+
+#: ajax/vcategories/add.php:36
+msgid "This category already exists: "
+msgstr ""
+
+#: js/jquery-ui-1.8.16.custom.min.js:511
+msgid "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
+msgstr ""
+
+#: js/js.js:519
+msgid "January"
+msgstr ""
+
+#: js/js.js:519
+msgid "February"
+msgstr ""
+
+#: js/js.js:519
+msgid "March"
+msgstr ""
+
+#: js/js.js:519
+msgid "April"
+msgstr ""
+
+#: js/js.js:519
+msgid "May"
+msgstr ""
+
+#: js/js.js:519
+msgid "June"
+msgstr ""
+
+#: js/js.js:520
+msgid "July"
+msgstr ""
+
+#: js/js.js:520
+msgid "August"
+msgstr ""
+
+#: js/js.js:520
+msgid "September"
+msgstr ""
+
+#: js/js.js:520
+msgid "October"
+msgstr ""
+
+#: js/js.js:520
+msgid "November"
+msgstr ""
+
+#: js/js.js:520
+msgid "December"
+msgstr ""
+
+#: js/oc-dialogs.js:143 js/oc-dialogs.js:163
+msgid "Cancel"
+msgstr ""
+
+#: js/oc-dialogs.js:159
+msgid "No"
+msgstr ""
+
+#: js/oc-dialogs.js:160
+msgid "Yes"
+msgstr ""
+
+#: js/oc-dialogs.js:177
+msgid "Ok"
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "Error"
+msgstr ""
+
+#: lostpassword/index.php:26
+msgid "ownCloud password reset"
+msgstr ""
+
+#: lostpassword/templates/email.php:1
+msgid "Use the following link to reset your password: {link}"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:3
+msgid "You will receive a link to reset your password via Email."
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:5
+msgid "Requested"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:8
+msgid "Login failed!"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:11 templates/installation.php:25
+#: templates/login.php:9
+msgid "Username"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:15
+msgid "Request reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:4
+msgid "Your password was reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:5
+msgid "To login page"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:8
+msgid "New password"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:11
+msgid "Reset password"
+msgstr ""
+
+#: strings.php:5
+msgid "Personal"
+msgstr ""
+
+#: strings.php:6
+msgid "Users"
+msgstr ""
+
+#: strings.php:7
+msgid "Apps"
+msgstr ""
+
+#: strings.php:8
+msgid "Admin"
+msgstr ""
+
+#: strings.php:9
+msgid "Help"
+msgstr ""
+
+#: templates/403.php:12
+msgid "Access forbidden"
+msgstr ""
+
+#: templates/404.php:12
+msgid "Cloud not found"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:4
+msgid "Edit categories"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:14
+msgid "Add"
+msgstr ""
+
+#: templates/installation.php:23
+msgid "Create an <strong>admin account</strong>"
+msgstr ""
+
+#: templates/installation.php:29 templates/login.php:13
+msgid "Password"
+msgstr ""
+
+#: templates/installation.php:35
+msgid "Advanced"
+msgstr ""
+
+#: templates/installation.php:37
+msgid "Data folder"
+msgstr ""
+
+#: templates/installation.php:44
+msgid "Configure the database"
+msgstr ""
+
+#: templates/installation.php:49 templates/installation.php:60
+#: templates/installation.php:70
+msgid "will be used"
+msgstr ""
+
+#: templates/installation.php:82
+msgid "Database user"
+msgstr ""
+
+#: templates/installation.php:86
+msgid "Database password"
+msgstr ""
+
+#: templates/installation.php:90
+msgid "Database name"
+msgstr ""
+
+#: templates/installation.php:96
+msgid "Database host"
+msgstr ""
+
+#: templates/installation.php:101
+msgid "Finish setup"
+msgstr ""
+
+#: templates/layout.guest.php:42
+msgid "web services under your control"
+msgstr ""
+
+#: templates/layout.user.php:49
+msgid "Log out"
+msgstr ""
+
+#: templates/layout.user.php:64 templates/layout.user.php:65
+msgid "Settings"
+msgstr ""
+
+#: templates/login.php:6
+msgid "Lost your password?"
+msgstr ""
+
+#: templates/login.php:17
+msgid "remember"
+msgstr ""
+
+#: templates/login.php:18
+msgid "Log in"
+msgstr ""
+
+#: templates/logout.php:1
+msgid "You are logged out."
+msgstr ""
+
+#: templates/part.pagenavi.php:3
+msgid "prev"
+msgstr ""
+
+#: templates/part.pagenavi.php:20
+msgid "next"
+msgstr ""
diff --git a/l10n/ar_SA/files.po b/l10n/ar_SA/files.po
new file mode 100644
index 00000000000..3b872219370
--- /dev/null
+++ b/l10n/ar_SA/files.po
@@ -0,0 +1,198 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/upload.php:20
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/upload.php:21
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/upload.php:22
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/upload.php:23
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/upload.php:24
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/upload.php:25
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/upload.php:26
+msgid "Failed to write to disk"
+msgstr ""
+
+#: appinfo/app.php:6
+msgid "Files"
+msgstr ""
+
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr ""
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr ""
+
+#: js/filelist.js:186
+msgid "undo deletion"
+msgstr ""
+
+#: js/files.js:170
+msgid "generating ZIP-file, it may take some time."
+msgstr ""
+
+#: js/files.js:199
+msgid "Unable to upload your file as it is a directory or has 0 bytes"
+msgstr ""
+
+#: js/files.js:199
+msgid "Upload Error"
+msgstr ""
+
+#: js/files.js:227 js/files.js:318 js/files.js:347
+msgid "Pending"
+msgstr ""
+
+#: js/files.js:332
+msgid "Upload cancelled."
+msgstr ""
+
+#: js/files.js:456
+msgid "Invalid name, '/' is not allowed."
+msgstr ""
+
+#: js/files.js:631 templates/index.php:55
+msgid "Size"
+msgstr ""
+
+#: js/files.js:632 templates/index.php:56
+msgid "Modified"
+msgstr ""
+
+#: js/files.js:659
+msgid "folder"
+msgstr ""
+
+#: js/files.js:661
+msgid "folders"
+msgstr ""
+
+#: js/files.js:669
+msgid "file"
+msgstr ""
+
+#: js/files.js:671
+msgid "files"
+msgstr ""
+
+#: templates/admin.php:5
+msgid "File handling"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "Maximum upload size"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "max. possible: "
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Needed for multi-file and folder downloads."
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Enable ZIP-download"
+msgstr ""
+
+#: templates/admin.php:11
+msgid "0 is unlimited"
+msgstr ""
+
+#: templates/admin.php:12
+msgid "Maximum input size for ZIP files"
+msgstr ""
+
+#: templates/index.php:7
+msgid "New"
+msgstr ""
+
+#: templates/index.php:9
+msgid "Text file"
+msgstr ""
+
+#: templates/index.php:10
+msgid "Folder"
+msgstr ""
+
+#: templates/index.php:11
+msgid "From url"
+msgstr ""
+
+#: templates/index.php:21
+msgid "Upload"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Cancel upload"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Nothing in here. Upload something!"
+msgstr ""
+
+#: templates/index.php:47
+msgid "Name"
+msgstr ""
+
+#: templates/index.php:49
+msgid "Share"
+msgstr ""
+
+#: templates/index.php:51
+msgid "Download"
+msgstr ""
+
+#: templates/index.php:64
+msgid "Upload too large"
+msgstr ""
+
+#: templates/index.php:66
+msgid ""
+"The files you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: templates/index.php:71
+msgid "Files are being scanned, please wait."
+msgstr ""
+
+#: templates/index.php:74
+msgid "Current scanning"
+msgstr ""
diff --git a/l10n/ar_SA/gallery.po b/l10n/ar_SA/gallery.po
new file mode 100644
index 00000000000..9d60ea7bc6d
--- /dev/null
+++ b/l10n/ar_SA/gallery.po
@@ -0,0 +1,58 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: appinfo/app.php:39
+msgid "Pictures"
+msgstr ""
+
+#: js/pictures.js:12
+msgid "Share gallery"
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Error: "
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Internal error"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr ""
+
+#: templates/view_album.php:19
+msgid "Back"
+msgstr ""
+
+#: templates/view_album.php:36
+msgid "Remove confirmation"
+msgstr ""
+
+#: templates/view_album.php:37
+msgid "Do you want to remove album"
+msgstr ""
+
+#: templates/view_album.php:40
+msgid "Change album name"
+msgstr ""
+
+#: templates/view_album.php:43
+msgid "New album name"
+msgstr ""
diff --git a/l10n/ar_SA/media.po b/l10n/ar_SA/media.po
new file mode 100644
index 00000000000..9f152efa421
--- /dev/null
+++ b/l10n/ar_SA/media.po
@@ -0,0 +1,66 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2011-08-13 02:19+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: appinfo/app.php:45 templates/player.php:8
+msgid "Music"
+msgstr ""
+
+#: js/music.js:18
+msgid "Add album to playlist"
+msgstr ""
+
+#: templates/music.php:3 templates/player.php:12
+msgid "Play"
+msgstr ""
+
+#: templates/music.php:4 templates/music.php:26 templates/player.php:13
+msgid "Pause"
+msgstr ""
+
+#: templates/music.php:5
+msgid "Previous"
+msgstr ""
+
+#: templates/music.php:6 templates/player.php:14
+msgid "Next"
+msgstr ""
+
+#: templates/music.php:7
+msgid "Mute"
+msgstr ""
+
+#: templates/music.php:8
+msgid "Unmute"
+msgstr ""
+
+#: templates/music.php:25
+msgid "Rescan Collection"
+msgstr ""
+
+#: templates/music.php:37
+msgid "Artist"
+msgstr ""
+
+#: templates/music.php:38
+msgid "Album"
+msgstr ""
+
+#: templates/music.php:39
+msgid "Title"
+msgstr ""
diff --git a/l10n/ar_SA/settings.po b/l10n/ar_SA/settings.po
new file mode 100644
index 00000000000..d4a0b648009
--- /dev/null
+++ b/l10n/ar_SA/settings.po
@@ -0,0 +1,206 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Arabic (Saudi Arabia) (http://www.transifex.com/projects/p/owncloud/language/ar_SA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar_SA\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/lostpassword.php:14
+msgid "Email saved"
+msgstr ""
+
+#: ajax/lostpassword.php:16
+msgid "Invalid email"
+msgstr ""
+
+#: ajax/openid.php:16
+msgid "OpenID Changed"
+msgstr ""
+
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
+msgid "Invalid request"
+msgstr ""
+
+#: ajax/setlanguage.php:18
+msgid "Language changed"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:67
+msgid "Disable"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:54
+msgid "Enable"
+msgstr ""
+
+#: js/personal.js:69
+msgid "Saving..."
+msgstr ""
+
+#: personal.php:41 personal.php:42
+msgid "__language_name__"
+msgstr ""
+
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr ""
+
+#: templates/admin.php:28
+msgid "Log"
+msgstr ""
+
+#: templates/admin.php:55
+msgid "More"
+msgstr ""
+
+#: templates/apps.php:10
+msgid "Add your App"
+msgstr ""
+
+#: templates/apps.php:24
+msgid "Select an App"
+msgstr ""
+
+#: templates/apps.php:27
+msgid "See application page at apps.owncloud.com"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "-licensed"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "by"
+msgstr ""
+
+#: templates/help.php:8
+msgid "Documentation"
+msgstr ""
+
+#: templates/help.php:9
+msgid "Managing Big Files"
+msgstr ""
+
+#: templates/help.php:10
+msgid "Ask a question"
+msgstr ""
+
+#: templates/help.php:22
+msgid "Problems connecting to help database."
+msgstr ""
+
+#: templates/help.php:23
+msgid "Go there manually."
+msgstr ""
+
+#: templates/help.php:31
+msgid "Answer"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "You use"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "of the available"
+msgstr ""
+
+#: templates/personal.php:12
+msgid "Desktop and Mobile Syncing Clients"
+msgstr ""
+
+#: templates/personal.php:13
+msgid "Download"
+msgstr ""
+
+#: templates/personal.php:19
+msgid "Your password got changed"
+msgstr ""
+
+#: templates/personal.php:20
+msgid "Unable to change your password"
+msgstr ""
+
+#: templates/personal.php:21
+msgid "Current password"
+msgstr ""
+
+#: templates/personal.php:22
+msgid "New password"
+msgstr ""
+
+#: templates/personal.php:23
+msgid "show"
+msgstr ""
+
+#: templates/personal.php:24
+msgid "Change password"
+msgstr ""
+
+#: templates/personal.php:30
+msgid "Email"
+msgstr ""
+
+#: templates/personal.php:31
+msgid "Your email address"
+msgstr ""
+
+#: templates/personal.php:32
+msgid "Fill in an email address to enable password recovery"
+msgstr ""
+
+#: templates/personal.php:38 templates/personal.php:39
+msgid "Language"
+msgstr ""
+
+#: templates/personal.php:44
+msgid "Help translate"
+msgstr ""
+
+#: templates/personal.php:51
+msgid "use this address to connect to your ownCloud in your file manager"
+msgstr ""
+
+#: templates/users.php:15 templates/users.php:60
+msgid "Name"
+msgstr ""
+
+#: templates/users.php:17 templates/users.php:61
+msgid "Password"
+msgstr ""
+
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
+msgid "Groups"
+msgstr ""
+
+#: templates/users.php:25
+msgid "Create"
+msgstr ""
+
+#: templates/users.php:28
+msgid "Default Quota"
+msgstr ""
+
+#: templates/users.php:47 templates/users.php:103
+msgid "Other"
+msgstr ""
+
+#: templates/users.php:63
+msgid "Quota"
+msgstr ""
+
+#: templates/users.php:110
+msgid "Delete"
+msgstr ""
diff --git a/l10n/de/calendar.po b/l10n/de/calendar.po
index 2e5af84f5a5..d129d8cae07 100644
--- a/l10n/de/calendar.po
+++ b/l10n/de/calendar.po
@@ -8,26 +8,36 @@
# Jan-Christoph Borchardt <JanCBorchardt@fsfe.org>, 2011.
# Jan-Christoph Borchardt <jan@unhosted.org>, 2011.
# Marcel Kühlhorn <susefan93@gmx.de>, 2012.
+# <niko@nik-o-mat.de>, 2012.
# <peddn@web.de>, 2012.
+# <thomas.mueller@tmit.eu>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:14+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/owncloud/language/de/)\n"
+"POT-Creation-Date: 2012-07-25 22:14+0200\n"
+"PO-Revision-Date: 2012-07-25 20:14+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ajax/categories/rescan.php:28
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
msgid "No calendars found."
msgstr "Keine Kalender gefunden"
-#: ajax/categories/rescan.php:36
+#: ajax/categories/rescan.php:37
msgid "No events found."
msgstr "Keine Termine gefunden"
@@ -35,300 +45,395 @@ msgstr "Keine Termine gefunden"
msgid "Wrong calendar"
msgstr "Falscher Kalender"
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr "Import fehlgeschlagen"
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
#: ajax/settings/guesstimezone.php:25
msgid "New Timezone:"
msgstr "Neue Zeitzone:"
-#: ajax/settings/settimezone.php:22
+#: ajax/settings/settimezone.php:23
msgid "Timezone changed"
msgstr "Zeitzone geändert"
-#: ajax/settings/settimezone.php:24
+#: ajax/settings/settimezone.php:25
msgid "Invalid request"
msgstr "Fehlerhafte Anfrage"
-#: appinfo/app.php:19 templates/calendar.php:15
-#: templates/part.eventform.php:33 templates/part.showevent.php:31
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
#: templates/settings.php:12
msgid "Calendar"
msgstr "Kalender"
-#: js/calendar.js:93
-msgid "Deletion failed"
-msgstr ""
-
#: js/calendar.js:828
msgid "ddd"
-msgstr ""
+msgstr "ddd"
#: js/calendar.js:829
msgid "ddd M/d"
-msgstr ""
+msgstr "ddd d.M"
#: js/calendar.js:830
msgid "dddd M/d"
-msgstr ""
+msgstr "dddd d.M"
#: js/calendar.js:833
msgid "MMMM yyyy"
-msgstr ""
+msgstr "MMMM yyyy"
#: js/calendar.js:835
msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
-msgstr "ddd d MMMM[ yyyy]{ -[ddd d] MMMM yyyy}"
+msgstr "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
#: js/calendar.js:837
msgid "dddd, MMM d, yyyy"
-msgstr ""
+msgstr "dddd, d. MMM yyyy"
-#: lib/app.php:125
+#: lib/app.php:121
msgid "Birthday"
msgstr "Geburtstag"
-#: lib/app.php:126
+#: lib/app.php:122
msgid "Business"
msgstr "Geschäftlich"
-#: lib/app.php:127
+#: lib/app.php:123
msgid "Call"
msgstr "Anruf"
-#: lib/app.php:128
+#: lib/app.php:124
msgid "Clients"
msgstr "Kunden"
-#: lib/app.php:129
+#: lib/app.php:125
msgid "Deliverer"
msgstr "Lieferant"
-#: lib/app.php:130
+#: lib/app.php:126
msgid "Holidays"
msgstr "Urlaub"
-#: lib/app.php:131
+#: lib/app.php:127
msgid "Ideas"
msgstr "Ideen"
-#: lib/app.php:132
+#: lib/app.php:128
msgid "Journey"
msgstr "Reise"
-#: lib/app.php:133
+#: lib/app.php:129
msgid "Jubilee"
msgstr "Jubiläum"
-#: lib/app.php:134
+#: lib/app.php:130
msgid "Meeting"
msgstr "Treffen"
-#: lib/app.php:135
+#: lib/app.php:131
msgid "Other"
msgstr "Anderes"
-#: lib/app.php:136
+#: lib/app.php:132
msgid "Personal"
msgstr "Persönlich"
-#: lib/app.php:137
+#: lib/app.php:133
msgid "Projects"
msgstr "Projekte"
-#: lib/app.php:138
+#: lib/app.php:134
msgid "Questions"
msgstr "Fragen"
-#: lib/app.php:139
+#: lib/app.php:135
msgid "Work"
msgstr "Arbeit"
-#: lib/app.php:380
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr "von"
+
+#: lib/app.php:359 lib/app.php:399
msgid "unnamed"
msgstr "unbenannt"
-#: lib/object.php:330
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr "Neuer Kalender"
+
+#: lib/object.php:372
msgid "Does not repeat"
msgstr "einmalig"
-#: lib/object.php:331
+#: lib/object.php:373
msgid "Daily"
msgstr "täglich"
-#: lib/object.php:332
+#: lib/object.php:374
msgid "Weekly"
msgstr "wöchentlich"
-#: lib/object.php:333
+#: lib/object.php:375
msgid "Every Weekday"
msgstr "jeden Wochentag"
-#: lib/object.php:334
+#: lib/object.php:376
msgid "Bi-Weekly"
msgstr "jede zweite Woche"
-#: lib/object.php:335
+#: lib/object.php:377
msgid "Monthly"
msgstr "monatlich"
-#: lib/object.php:336
+#: lib/object.php:378
msgid "Yearly"
msgstr "jährlich"
-#: lib/object.php:343
+#: lib/object.php:388
msgid "never"
msgstr "niemals"
-#: lib/object.php:344
+#: lib/object.php:389
msgid "by occurrences"
msgstr "nach Terminen"
-#: lib/object.php:345
+#: lib/object.php:390
msgid "by date"
msgstr "nach Datum"
-#: lib/object.php:352
+#: lib/object.php:400
msgid "by monthday"
msgstr "an einem Monatstag"
-#: lib/object.php:353
+#: lib/object.php:401
msgid "by weekday"
msgstr "an einem Wochentag"
-#: lib/object.php:360 templates/settings.php:42
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
msgid "Monday"
msgstr "Montag"
-#: lib/object.php:361
+#: lib/object.php:412 templates/calendar.php:5
msgid "Tuesday"
msgstr "Dienstag"
-#: lib/object.php:362
+#: lib/object.php:413 templates/calendar.php:5
msgid "Wednesday"
msgstr "Mittwoch"
-#: lib/object.php:363
+#: lib/object.php:414 templates/calendar.php:5
msgid "Thursday"
msgstr "Donnerstag"
-#: lib/object.php:364
+#: lib/object.php:415 templates/calendar.php:5
msgid "Friday"
msgstr "Freitag"
-#: lib/object.php:365
+#: lib/object.php:416 templates/calendar.php:5
msgid "Saturday"
msgstr "Samstag"
-#: lib/object.php:366 templates/settings.php:43
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
msgid "Sunday"
msgstr "Sonntag"
-#: lib/object.php:373
+#: lib/object.php:427
msgid "events week of month"
msgstr "Woche des Monats vom Termin"
-#: lib/object.php:374
+#: lib/object.php:428
msgid "first"
msgstr "erste"
-#: lib/object.php:375
+#: lib/object.php:429
msgid "second"
msgstr "zweite"
-#: lib/object.php:376
+#: lib/object.php:430
msgid "third"
msgstr "dritte"
-#: lib/object.php:377
+#: lib/object.php:431
msgid "fourth"
msgstr "vierte"
-#: lib/object.php:378
+#: lib/object.php:432
msgid "fifth"
msgstr "fünfte"
-#: lib/object.php:379
+#: lib/object.php:433
msgid "last"
msgstr "letzte"
-#: lib/object.php:401
+#: lib/object.php:467 templates/calendar.php:7
msgid "January"
msgstr "Januar"
-#: lib/object.php:402
+#: lib/object.php:468 templates/calendar.php:7
msgid "February"
msgstr "Februar"
-#: lib/object.php:403
+#: lib/object.php:469 templates/calendar.php:7
msgid "March"
msgstr "März"
-#: lib/object.php:404
+#: lib/object.php:470 templates/calendar.php:7
msgid "April"
msgstr "April"
-#: lib/object.php:405
+#: lib/object.php:471 templates/calendar.php:7
msgid "May"
msgstr "Mai"
-#: lib/object.php:406
+#: lib/object.php:472 templates/calendar.php:7
msgid "June"
msgstr "Juni"
-#: lib/object.php:407
+#: lib/object.php:473 templates/calendar.php:7
msgid "July"
msgstr "Juli"
-#: lib/object.php:408
+#: lib/object.php:474 templates/calendar.php:7
msgid "August"
msgstr "August"
-#: lib/object.php:409
+#: lib/object.php:475 templates/calendar.php:7
msgid "September"
msgstr "September"
-#: lib/object.php:410
+#: lib/object.php:476 templates/calendar.php:7
msgid "October"
msgstr "Oktober"
-#: lib/object.php:411
+#: lib/object.php:477 templates/calendar.php:7
msgid "November"
msgstr "November"
-#: lib/object.php:412
+#: lib/object.php:478 templates/calendar.php:7
msgid "December"
msgstr "Dezember"
-#: lib/object.php:418
+#: lib/object.php:488
msgid "by events date"
msgstr "nach Tag des Termins"
-#: lib/object.php:419
+#: lib/object.php:489
msgid "by yearday(s)"
msgstr "nach Tag des Jahres"
-#: lib/object.php:420
+#: lib/object.php:490
msgid "by weeknumber(s)"
msgstr "nach Wochennummer"
-#: lib/object.php:421
+#: lib/object.php:491
msgid "by day and month"
msgstr "nach Tag und Monat"
-#: lib/search.php:32 lib/search.php:34 lib/search.php:37
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
msgid "Date"
msgstr "Datum"
-#: lib/search.php:40
+#: lib/search.php:43
msgid "Cal."
msgstr "Kal."
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr "So"
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr "Mo"
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr "Di"
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr "Mi"
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr "Do"
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr "Fr"
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr "Sa"
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr "Jan."
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr "Feb."
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr "Mär."
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr "Apr."
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr "Mai"
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr "Jun."
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr "Jul."
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr "Aug."
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr "Sep."
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr "Okt."
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr "Nov."
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr "Dez."
+
#: templates/calendar.php:11
msgid "All day"
msgstr "Ganztags"
-#: templates/calendar.php:12 templates/part.choosecalendar.php:22
-msgid "New Calendar"
-msgstr "Neuer Kalender"
-
#: templates/calendar.php:13
msgid "Missing fields"
msgstr "fehlende Felder"
@@ -362,27 +467,27 @@ msgstr "Der Termin hört auf, bevor er angefangen hat."
msgid "There was a database fail"
msgstr "Datenbankfehler"
-#: templates/calendar.php:40
+#: templates/calendar.php:38
msgid "Week"
msgstr "Woche"
-#: templates/calendar.php:41
+#: templates/calendar.php:39
msgid "Month"
msgstr "Monat"
-#: templates/calendar.php:42
+#: templates/calendar.php:40
msgid "List"
msgstr "Liste"
-#: templates/calendar.php:48
+#: templates/calendar.php:44
msgid "Today"
msgstr "Heute"
-#: templates/calendar.php:49
+#: templates/calendar.php:45
msgid "Calendars"
msgstr "Kalender"
-#: templates/calendar.php:67
+#: templates/calendar.php:59
msgid "There was a fail, while parsing the file."
msgstr "Fehler beim Einlesen der Datei."
@@ -395,7 +500,7 @@ msgid "Your calendars"
msgstr "Deine Kalender"
#: templates/part.choosecalendar.php:27
-#: templates/part.choosecalendar.rowfields.php:5
+#: templates/part.choosecalendar.rowfields.php:11
msgid "CalDav Link"
msgstr "CalDAV-Link"
@@ -407,19 +512,19 @@ msgstr "geteilte Kalender"
msgid "No shared calendars"
msgstr "Keine geteilten Kalender"
-#: templates/part.choosecalendar.rowfields.php:4
+#: templates/part.choosecalendar.rowfields.php:8
msgid "Share Calendar"
msgstr "Kalender teilen"
-#: templates/part.choosecalendar.rowfields.php:6
+#: templates/part.choosecalendar.rowfields.php:14
msgid "Download"
msgstr "Herunterladen"
-#: templates/part.choosecalendar.rowfields.php:7
+#: templates/part.choosecalendar.rowfields.php:17
msgid "Edit"
msgstr "Bearbeiten"
-#: templates/part.choosecalendar.rowfields.php:8
+#: templates/part.choosecalendar.rowfields.php:20
#: templates/part.editevent.php:9
msgid "Delete"
msgstr "Löschen"
@@ -505,23 +610,23 @@ msgstr "Kategorien mit Kommas trennen"
msgid "Edit categories"
msgstr "Kategorien ändern"
-#: templates/part.eventform.php:56 templates/part.showevent.php:55
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
msgid "All Day Event"
msgstr "Ganztägiges Ereignis"
-#: templates/part.eventform.php:60 templates/part.showevent.php:59
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
msgid "From"
msgstr "von"
-#: templates/part.eventform.php:68 templates/part.showevent.php:67
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
msgid "To"
msgstr "bis"
-#: templates/part.eventform.php:76 templates/part.showevent.php:75
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
msgid "Advanced options"
msgstr "Erweiterte Optionen"
-#: templates/part.eventform.php:81 templates/part.showevent.php:80
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
msgid "Location"
msgstr "Ort"
@@ -529,7 +634,7 @@ msgstr "Ort"
msgid "Location of the Event"
msgstr "Ort"
-#: templates/part.eventform.php:89 templates/part.showevent.php:88
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
msgid "Description"
msgstr "Beschreibung"
@@ -537,84 +642,86 @@ msgstr "Beschreibung"
msgid "Description of the Event"
msgstr "Beschreibung"
-#: templates/part.eventform.php:100 templates/part.showevent.php:98
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
msgid "Repeat"
msgstr "wiederholen"
-#: templates/part.eventform.php:107 templates/part.showevent.php:105
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
msgid "Advanced"
msgstr "Erweitert"
-#: templates/part.eventform.php:151 templates/part.showevent.php:149
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
msgid "Select weekdays"
msgstr "Wochentage auswählen"
#: templates/part.eventform.php:164 templates/part.eventform.php:177
-#: templates/part.showevent.php:162 templates/part.showevent.php:175
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
msgid "Select days"
msgstr "Tage auswählen"
-#: templates/part.eventform.php:169 templates/part.showevent.php:167
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
msgid "and the events day of year."
msgstr "und den Tag des Jahres vom Termin"
-#: templates/part.eventform.php:182 templates/part.showevent.php:180
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
msgid "and the events day of month."
msgstr "und den Tag des Monats vom Termin"
-#: templates/part.eventform.php:190 templates/part.showevent.php:188
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
msgid "Select months"
msgstr "Monate auswählen"
-#: templates/part.eventform.php:203 templates/part.showevent.php:201
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
msgid "Select weeks"
msgstr "Wochen auswählen"
-#: templates/part.eventform.php:208 templates/part.showevent.php:206
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
msgid "and the events week of year."
msgstr "und den Tag des Jahres vom Termin"
-#: templates/part.eventform.php:214 templates/part.showevent.php:212
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
msgid "Interval"
msgstr "Intervall"
-#: templates/part.eventform.php:220 templates/part.showevent.php:218
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
msgid "End"
msgstr "Ende"
-#: templates/part.eventform.php:233 templates/part.showevent.php:231
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
msgid "occurrences"
msgstr "Termine"
-#: templates/part.import.php:1
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr "Neuen Kalender anlegen"
+
+#: templates/part.import.php:17
msgid "Import a calendar file"
msgstr "Kalenderdatei Importieren"
-#: templates/part.import.php:6
-msgid "Please choose the calendar"
-msgstr "Bitte wählen Sie den Kalender."
-
-#: templates/part.import.php:10
-msgid "create a new calendar"
-msgstr "Neuen Kalender anlegen"
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr ""
-#: templates/part.import.php:15
+#: templates/part.import.php:36
msgid "Name of new calendar"
msgstr "Kalendername"
-#: templates/part.import.php:17
-msgid "Import"
-msgstr "Importieren"
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr ""
-#: templates/part.import.php:20
-msgid "Importing calendar"
-msgstr "Kalender wird importiert."
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr ""
-#: templates/part.import.php:23
-msgid "Calendar imported successfully"
-msgstr "Kalender erfolgreich importiert"
+#: templates/part.import.php:47
+msgid "Import"
+msgstr "Importieren"
-#: templates/part.import.php:24
+#: templates/part.import.php:56
msgid "Close Dialog"
msgstr "Dialog schließen"
@@ -630,15 +737,11 @@ msgstr "Termin öffnen"
msgid "No categories selected"
msgstr "Keine Kategorie ausgewählt"
-#: templates/part.showevent.php:25
-msgid "Select category"
-msgstr "Kategorie auswählen"
-
#: templates/part.showevent.php:37
msgid "of"
msgstr "von"
-#: templates/part.showevent.php:62 templates/part.showevent.php:70
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
msgid "at"
msgstr "um"
@@ -666,17 +769,41 @@ msgstr "12h"
msgid "First day of the week"
msgstr "erster Wochentag"
-#: templates/settings.php:49
-msgid "Calendar CalDAV syncing address:"
-msgstr "Kalender CalDAV Synchronisationsadresse:"
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr ""
#: templates/share.dropdown.php:20
msgid "Users"
-msgstr "Nutzer"
+msgstr "Benutzer"
#: templates/share.dropdown.php:21
msgid "select users"
-msgstr "Nutzer auswählen"
+msgstr "Benutzer auswählen"
#: templates/share.dropdown.php:36 templates/share.dropdown.php:62
msgid "Editable"
diff --git a/l10n/de/gallery.po b/l10n/de/gallery.po
index 50151756004..ec9656fa93f 100644
--- a/l10n/de/gallery.po
+++ b/l10n/de/gallery.po
@@ -6,75 +6,41 @@
# <admin@s-goecker.de>, 2012.
# Bartek <bart.p.pl@gmail.com>, 2012.
# Marcel Kühlhorn <susefan93@gmx.de>, 2012.
+# <niko@nik-o-mat.de>, 2012.
+# <thomas.mueller@tmit.eu>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: German (http://www.transifex.net/projects/p/owncloud/language/de/)\n"
+"POT-Creation-Date: 2012-07-25 22:14+0200\n"
+"PO-Revision-Date: 2012-07-25 20:05+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: German (http://www.transifex.com/projects/p/owncloud/language/de/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: de\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: appinfo/app.php:37
+#: appinfo/app.php:39
msgid "Pictures"
msgstr "Bilder"
-#: js/album_cover.js:44
+#: js/pictures.js:12
msgid "Share gallery"
-msgstr ""
+msgstr "Galerie teilen"
-#: js/album_cover.js:64 js/album_cover.js:100 js/album_cover.js:133
+#: js/pictures.js:32
msgid "Error: "
-msgstr ""
+msgstr "Fehler:"
-#: js/album_cover.js:64 js/album_cover.js:100
+#: js/pictures.js:32
msgid "Internal error"
-msgstr ""
-
-#: js/album_cover.js:114
-msgid "Scanning root"
-msgstr ""
-
-#: js/album_cover.js:115
-msgid "Default order"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Ascending"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Descending"
-msgstr ""
-
-#: js/album_cover.js:117 templates/index.php:19
-msgid "Settings"
-msgstr "Einstellungen"
-
-#: js/album_cover.js:122
-msgid "Scanning root cannot be empty"
-msgstr ""
-
-#: js/album_cover.js:122 js/album_cover.js:133
-msgid "Error"
-msgstr ""
-
-#: templates/index.php:16
-msgid "Rescan"
-msgstr "Erneut Scannen"
-
-#: templates/index.php:17
-msgid "Stop"
-msgstr "Stopp"
+msgstr "Interner Fehler"
-#: templates/index.php:18
-msgid "Share"
-msgstr "Teilen"
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr "Slideshow"
#: templates/view_album.php:19
msgid "Back"
diff --git a/l10n/es/files.po b/l10n/es/files.po
index 4e4b0b0c2d6..ccd3fc76a0b 100644
--- a/l10n/es/files.po
+++ b/l10n/es/files.po
@@ -4,48 +4,49 @@
#
# Translators:
# Javier Llorente <javier@opensuse.org>, 2012.
+# <juanma@kde.org.ar>, 2012.
# <sergioballesterossolanas@gmail.com>, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/owncloud/language/es/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 23:05+0000\n"
+"Last-Translator: juanman <juanma@kde.org.ar>\n"
+"Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ajax/upload.php:19
+#: ajax/upload.php:20
msgid "There is no error, the file uploaded with success"
msgstr "No se ha producido ningún error, el archivo se ha subido con éxito"
-#: ajax/upload.php:20
+#: ajax/upload.php:21
msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
msgstr "El archivo que intentas subir sobrepasa el tamaño definido por la variable upload_max_filesize en php.ini"
-#: ajax/upload.php:21
+#: ajax/upload.php:22
msgid ""
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
"the HTML form"
msgstr "El archivo que intentas subir sobrepasa el tamaño definido por la variable MAX_FILE_SIZE especificada en el formulario HTML"
-#: ajax/upload.php:22
+#: ajax/upload.php:23
msgid "The uploaded file was only partially uploaded"
msgstr "El archivo que intentas subir solo se subió parcialmente"
-#: ajax/upload.php:23
+#: ajax/upload.php:24
msgid "No file was uploaded"
msgstr "No se ha subido ningún archivo"
-#: ajax/upload.php:24
+#: ajax/upload.php:25
msgid "Missing a temporary folder"
msgstr "Falta un directorio temporal"
-#: ajax/upload.php:25
+#: ajax/upload.php:26
msgid "Failed to write to disk"
msgstr "La escritura en disco ha fallado"
@@ -53,57 +54,65 @@ msgstr "La escritura en disco ha fallado"
msgid "Files"
msgstr "Archivos"
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr "No compartir"
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr "Eliminado"
+
#: js/filelist.js:186
msgid "undo deletion"
-msgstr ""
+msgstr "deshacer la eliminación"
#: js/files.js:170
msgid "generating ZIP-file, it may take some time."
-msgstr ""
+msgstr "generando un fichero ZIP, puede llevar un tiempo."
#: js/files.js:199
msgid "Unable to upload your file as it is a directory or has 0 bytes"
-msgstr ""
+msgstr "No ha sido posible subir tu archivo porque es un directorio o tiene 0 bytes"
#: js/files.js:199
msgid "Upload Error"
-msgstr ""
+msgstr "Error al subir el archivo"
#: js/files.js:227 js/files.js:318 js/files.js:347
msgid "Pending"
-msgstr ""
+msgstr "Pendiente"
#: js/files.js:332
msgid "Upload cancelled."
-msgstr ""
+msgstr "Subida cancelada."
#: js/files.js:456
msgid "Invalid name, '/' is not allowed."
-msgstr ""
+msgstr "Nombre no válido, '/' no está permitido."
-#: js/files.js:626 templates/index.php:55
+#: js/files.js:631 templates/index.php:55
msgid "Size"
msgstr "Tamaño"
-#: js/files.js:627 templates/index.php:56
+#: js/files.js:632 templates/index.php:56
msgid "Modified"
msgstr "Modificado"
-#: js/files.js:654
+#: js/files.js:659
msgid "folder"
-msgstr ""
+msgstr "carpeta"
-#: js/files.js:656
+#: js/files.js:661
msgid "folders"
-msgstr ""
+msgstr "carpetas"
-#: js/files.js:664
+#: js/files.js:669
msgid "file"
-msgstr ""
+msgstr "archivo"
-#: js/files.js:666
+#: js/files.js:671
msgid "files"
-msgstr ""
+msgstr "archivos"
#: templates/admin.php:5
msgid "File handling"
@@ -173,10 +182,6 @@ msgstr "Compartir"
msgid "Download"
msgstr "Descargar"
-#: templates/index.php:56
-msgid "Delete"
-msgstr "Eliminado"
-
#: templates/index.php:64
msgid "Upload too large"
msgstr "El archivo es demasiado grande"
diff --git a/l10n/es/gallery.po b/l10n/es/gallery.po
index 94068028c61..8a67c771871 100644
--- a/l10n/es/gallery.po
+++ b/l10n/es/gallery.po
@@ -5,76 +5,41 @@
# Translators:
# Javier Llorente <javier@opensuse.org>, 2012.
# <juanma@kde.org.ar>, 2012.
+# <rodrigo.calvo@gmail.com>, 2012.
# <sergioballesterossolanas@gmail.com>, 2012.
msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/owncloud/language/es/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 23:13+0000\n"
+"Last-Translator: juanman <juanma@kde.org.ar>\n"
+"Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: es\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: appinfo/app.php:37
+#: appinfo/app.php:39
msgid "Pictures"
msgstr "Imágenes"
-#: js/album_cover.js:44
+#: js/pictures.js:12
msgid "Share gallery"
-msgstr ""
+msgstr "Compartir galería"
-#: js/album_cover.js:64 js/album_cover.js:100 js/album_cover.js:133
+#: js/pictures.js:32
msgid "Error: "
-msgstr ""
+msgstr "Fallo "
-#: js/album_cover.js:64 js/album_cover.js:100
+#: js/pictures.js:32
msgid "Internal error"
-msgstr ""
-
-#: js/album_cover.js:114
-msgid "Scanning root"
-msgstr ""
-
-#: js/album_cover.js:115
-msgid "Default order"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Ascending"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Descending"
-msgstr ""
-
-#: js/album_cover.js:117 templates/index.php:19
-msgid "Settings"
-msgstr "Preferencias"
-
-#: js/album_cover.js:122
-msgid "Scanning root cannot be empty"
-msgstr ""
-
-#: js/album_cover.js:122 js/album_cover.js:133
-msgid "Error"
-msgstr ""
-
-#: templates/index.php:16
-msgid "Rescan"
-msgstr "Refrescar"
-
-#: templates/index.php:17
-msgid "Stop"
-msgstr "Parar"
+msgstr "Fallo interno"
-#: templates/index.php:18
-msgid "Share"
-msgstr "Compartir"
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr "Presentación"
#: templates/view_album.php:19
msgid "Back"
diff --git a/l10n/es/settings.po b/l10n/es/settings.po
index a8cb655556f..d594551c6e3 100644
--- a/l10n/es/settings.po
+++ b/l10n/es/settings.po
@@ -7,16 +7,17 @@
# <juanma@kde.org.ar>, 2011, 2012.
# <monty_2731@hotmail.com>, 2011.
# oSiNaReF <>, 2012.
+# <rodrigo.calvo@gmail.com>, 2012.
# <rom1dep@gmail.com>, 2011.
# <sergioballesterossolanas@gmail.com>, 2011, 2012.
msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Spanish (Castilian) (http://www.transifex.net/projects/p/owncloud/language/es/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 23:06+0000\n"
+"Last-Translator: juanman <juanma@kde.org.ar>\n"
+"Language-Team: Spanish (http://www.transifex.com/projects/p/owncloud/language/es/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -25,65 +26,69 @@ msgstr ""
#: ajax/lostpassword.php:14
msgid "Email saved"
-msgstr ""
+msgstr "Correo salvado"
#: ajax/lostpassword.php:16
msgid "Invalid email"
-msgstr ""
+msgstr "Correo Incorrecto"
-#: ajax/openid.php:15
+#: ajax/openid.php:16
msgid "OpenID Changed"
msgstr "OpenID cambiado"
-#: ajax/openid.php:17 ajax/setlanguage.php:19 ajax/setlanguage.php:22
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
msgid "Invalid request"
msgstr "Solicitud no válida"
-#: ajax/setlanguage.php:17
+#: ajax/setlanguage.php:18
msgid "Language changed"
msgstr "Idioma cambiado"
#: js/apps.js:31 js/apps.js:67
msgid "Disable"
-msgstr ""
+msgstr "Desactivar"
#: js/apps.js:31 js/apps.js:54
msgid "Enable"
-msgstr ""
+msgstr "Activar"
#: js/personal.js:69
msgid "Saving..."
-msgstr ""
+msgstr "Salvando.."
-#: personal.php:40 personal.php:41
+#: personal.php:41 personal.php:42
msgid "__language_name__"
msgstr "Castellano"
-#: templates/admin.php:13
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr "Advertencia de seguridad"
+
+#: templates/admin.php:28
msgid "Log"
msgstr "Registro"
-#: templates/admin.php:40
+#: templates/admin.php:55
msgid "More"
msgstr "Más"
-#: templates/apps.php:8
+#: templates/apps.php:10
msgid "Add your App"
msgstr "Añade tu aplicación"
-#: templates/apps.php:22
+#: templates/apps.php:24
msgid "Select an App"
msgstr "Seleccionar una aplicación"
-#: templates/apps.php:25
+#: templates/apps.php:27
msgid "See application page at apps.owncloud.com"
-msgstr ""
+msgstr "Revisa la web de apps apps.owncloud.com"
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "-licensed"
msgstr "-autorizado"
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "by"
msgstr "por"
@@ -175,34 +180,34 @@ msgstr "Ayúdanos a traducir"
msgid "use this address to connect to your ownCloud in your file manager"
msgstr "utiliza esta dirección para conectar a tu ownCloud desde tu gestor de archivos"
-#: templates/users.php:15 templates/users.php:44
+#: templates/users.php:15 templates/users.php:60
msgid "Name"
msgstr "Nombre"
-#: templates/users.php:16 templates/users.php:45
+#: templates/users.php:17 templates/users.php:61
msgid "Password"
msgstr "Contraseña"
-#: templates/users.php:17 templates/users.php:46 templates/users.php:60
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
msgid "Groups"
msgstr "Grupos"
-#: templates/users.php:22
+#: templates/users.php:25
msgid "Create"
msgstr "Crear"
-#: templates/users.php:25
+#: templates/users.php:28
msgid "Default Quota"
msgstr "Cuota predeterminada"
-#: templates/users.php:35 templates/users.php:74
+#: templates/users.php:47 templates/users.php:103
msgid "Other"
msgstr "Otro"
-#: templates/users.php:47
+#: templates/users.php:63
msgid "Quota"
msgstr "Cuota"
-#: templates/users.php:80
+#: templates/users.php:110
msgid "Delete"
msgstr "Eliminar"
diff --git a/l10n/id_ID/calendar.po b/l10n/id_ID/calendar.po
new file mode 100644
index 00000000000..ac6c2362a01
--- /dev/null
+++ b/l10n/id_ID/calendar.po
@@ -0,0 +1,814 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
+msgid "No calendars found."
+msgstr ""
+
+#: ajax/categories/rescan.php:37
+msgid "No events found."
+msgstr ""
+
+#: ajax/event/edit.form.php:20
+msgid "Wrong calendar"
+msgstr ""
+
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr ""
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
+#: ajax/settings/guesstimezone.php:25
+msgid "New Timezone:"
+msgstr ""
+
+#: ajax/settings/settimezone.php:23
+msgid "Timezone changed"
+msgstr ""
+
+#: ajax/settings/settimezone.php:25
+msgid "Invalid request"
+msgstr ""
+
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
+#: templates/settings.php:12
+msgid "Calendar"
+msgstr ""
+
+#: js/calendar.js:828
+msgid "ddd"
+msgstr ""
+
+#: js/calendar.js:829
+msgid "ddd M/d"
+msgstr ""
+
+#: js/calendar.js:830
+msgid "dddd M/d"
+msgstr ""
+
+#: js/calendar.js:833
+msgid "MMMM yyyy"
+msgstr ""
+
+#: js/calendar.js:835
+msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
+msgstr ""
+
+#: js/calendar.js:837
+msgid "dddd, MMM d, yyyy"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:122
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:129
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:130
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:131
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:132
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:133
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Questions"
+msgstr ""
+
+#: lib/app.php:135
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr ""
+
+#: lib/app.php:359 lib/app.php:399
+msgid "unnamed"
+msgstr ""
+
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr ""
+
+#: lib/object.php:372
+msgid "Does not repeat"
+msgstr ""
+
+#: lib/object.php:373
+msgid "Daily"
+msgstr ""
+
+#: lib/object.php:374
+msgid "Weekly"
+msgstr ""
+
+#: lib/object.php:375
+msgid "Every Weekday"
+msgstr ""
+
+#: lib/object.php:376
+msgid "Bi-Weekly"
+msgstr ""
+
+#: lib/object.php:377
+msgid "Monthly"
+msgstr ""
+
+#: lib/object.php:378
+msgid "Yearly"
+msgstr ""
+
+#: lib/object.php:388
+msgid "never"
+msgstr ""
+
+#: lib/object.php:389
+msgid "by occurrences"
+msgstr ""
+
+#: lib/object.php:390
+msgid "by date"
+msgstr ""
+
+#: lib/object.php:400
+msgid "by monthday"
+msgstr ""
+
+#: lib/object.php:401
+msgid "by weekday"
+msgstr ""
+
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
+msgid "Monday"
+msgstr ""
+
+#: lib/object.php:412 templates/calendar.php:5
+msgid "Tuesday"
+msgstr ""
+
+#: lib/object.php:413 templates/calendar.php:5
+msgid "Wednesday"
+msgstr ""
+
+#: lib/object.php:414 templates/calendar.php:5
+msgid "Thursday"
+msgstr ""
+
+#: lib/object.php:415 templates/calendar.php:5
+msgid "Friday"
+msgstr ""
+
+#: lib/object.php:416 templates/calendar.php:5
+msgid "Saturday"
+msgstr ""
+
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
+msgid "Sunday"
+msgstr ""
+
+#: lib/object.php:427
+msgid "events week of month"
+msgstr ""
+
+#: lib/object.php:428
+msgid "first"
+msgstr ""
+
+#: lib/object.php:429
+msgid "second"
+msgstr ""
+
+#: lib/object.php:430
+msgid "third"
+msgstr ""
+
+#: lib/object.php:431
+msgid "fourth"
+msgstr ""
+
+#: lib/object.php:432
+msgid "fifth"
+msgstr ""
+
+#: lib/object.php:433
+msgid "last"
+msgstr ""
+
+#: lib/object.php:467 templates/calendar.php:7
+msgid "January"
+msgstr ""
+
+#: lib/object.php:468 templates/calendar.php:7
+msgid "February"
+msgstr ""
+
+#: lib/object.php:469 templates/calendar.php:7
+msgid "March"
+msgstr ""
+
+#: lib/object.php:470 templates/calendar.php:7
+msgid "April"
+msgstr ""
+
+#: lib/object.php:471 templates/calendar.php:7
+msgid "May"
+msgstr ""
+
+#: lib/object.php:472 templates/calendar.php:7
+msgid "June"
+msgstr ""
+
+#: lib/object.php:473 templates/calendar.php:7
+msgid "July"
+msgstr ""
+
+#: lib/object.php:474 templates/calendar.php:7
+msgid "August"
+msgstr ""
+
+#: lib/object.php:475 templates/calendar.php:7
+msgid "September"
+msgstr ""
+
+#: lib/object.php:476 templates/calendar.php:7
+msgid "October"
+msgstr ""
+
+#: lib/object.php:477 templates/calendar.php:7
+msgid "November"
+msgstr ""
+
+#: lib/object.php:478 templates/calendar.php:7
+msgid "December"
+msgstr ""
+
+#: lib/object.php:488
+msgid "by events date"
+msgstr ""
+
+#: lib/object.php:489
+msgid "by yearday(s)"
+msgstr ""
+
+#: lib/object.php:490
+msgid "by weeknumber(s)"
+msgstr ""
+
+#: lib/object.php:491
+msgid "by day and month"
+msgstr ""
+
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
+msgid "Date"
+msgstr ""
+
+#: lib/search.php:43
+msgid "Cal."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr ""
+
+#: templates/calendar.php:11
+msgid "All day"
+msgstr ""
+
+#: templates/calendar.php:13
+msgid "Missing fields"
+msgstr ""
+
+#: templates/calendar.php:14 templates/part.eventform.php:19
+#: templates/part.showevent.php:11
+msgid "Title"
+msgstr ""
+
+#: templates/calendar.php:16
+msgid "From Date"
+msgstr ""
+
+#: templates/calendar.php:17
+msgid "From Time"
+msgstr ""
+
+#: templates/calendar.php:18
+msgid "To Date"
+msgstr ""
+
+#: templates/calendar.php:19
+msgid "To Time"
+msgstr ""
+
+#: templates/calendar.php:20
+msgid "The event ends before it starts"
+msgstr ""
+
+#: templates/calendar.php:21
+msgid "There was a database fail"
+msgstr ""
+
+#: templates/calendar.php:38
+msgid "Week"
+msgstr ""
+
+#: templates/calendar.php:39
+msgid "Month"
+msgstr ""
+
+#: templates/calendar.php:40
+msgid "List"
+msgstr ""
+
+#: templates/calendar.php:44
+msgid "Today"
+msgstr ""
+
+#: templates/calendar.php:45
+msgid "Calendars"
+msgstr ""
+
+#: templates/calendar.php:59
+msgid "There was a fail, while parsing the file."
+msgstr ""
+
+#: templates/part.choosecalendar.php:1
+msgid "Choose active calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:2
+msgid "Your calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:27
+#: templates/part.choosecalendar.rowfields.php:11
+msgid "CalDav Link"
+msgstr ""
+
+#: templates/part.choosecalendar.php:31
+msgid "Shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:48
+msgid "No shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:8
+msgid "Share Calendar"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:14
+msgid "Download"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:17
+msgid "Edit"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:20
+#: templates/part.editevent.php:9
+msgid "Delete"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.shared.php:4
+msgid "shared with you by"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "New calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "Edit calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editcalendar.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editcalendar.php:29
+msgid "Calendar color"
+msgstr ""
+
+#: templates/part.editcalendar.php:42
+msgid "Save"
+msgstr ""
+
+#: templates/part.editcalendar.php:42 templates/part.editevent.php:8
+#: templates/part.newevent.php:6
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editcalendar.php:43
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.editevent.php:1
+msgid "Edit an event"
+msgstr ""
+
+#: templates/part.editevent.php:10
+msgid "Export"
+msgstr ""
+
+#: templates/part.eventform.php:8 templates/part.showevent.php:3
+msgid "Eventinfo"
+msgstr ""
+
+#: templates/part.eventform.php:9 templates/part.showevent.php:4
+msgid "Repeating"
+msgstr ""
+
+#: templates/part.eventform.php:10 templates/part.showevent.php:5
+msgid "Alarm"
+msgstr ""
+
+#: templates/part.eventform.php:11 templates/part.showevent.php:6
+msgid "Attendees"
+msgstr ""
+
+#: templates/part.eventform.php:13
+msgid "Share"
+msgstr ""
+
+#: templates/part.eventform.php:21
+msgid "Title of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:27 templates/part.showevent.php:19
+msgid "Category"
+msgstr ""
+
+#: templates/part.eventform.php:29
+msgid "Separate categories with commas"
+msgstr ""
+
+#: templates/part.eventform.php:30
+msgid "Edit categories"
+msgstr ""
+
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
+msgid "All Day Event"
+msgstr ""
+
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
+msgid "From"
+msgstr ""
+
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
+msgid "To"
+msgstr ""
+
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
+msgid "Advanced options"
+msgstr ""
+
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
+msgid "Location"
+msgstr ""
+
+#: templates/part.eventform.php:83
+msgid "Location of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
+msgid "Description"
+msgstr ""
+
+#: templates/part.eventform.php:91
+msgid "Description of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
+msgid "Repeat"
+msgstr ""
+
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
+msgid "Advanced"
+msgstr ""
+
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
+msgid "Select weekdays"
+msgstr ""
+
+#: templates/part.eventform.php:164 templates/part.eventform.php:177
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
+msgid "Select days"
+msgstr ""
+
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
+msgid "and the events day of year."
+msgstr ""
+
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
+msgid "and the events day of month."
+msgstr ""
+
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
+msgid "Select months"
+msgstr ""
+
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
+msgid "Select weeks"
+msgstr ""
+
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
+msgid "and the events week of year."
+msgstr ""
+
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
+msgid "Interval"
+msgstr ""
+
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
+msgid "End"
+msgstr ""
+
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
+msgid "occurrences"
+msgstr ""
+
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr ""
+
+#: templates/part.import.php:17
+msgid "Import a calendar file"
+msgstr ""
+
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr ""
+
+#: templates/part.import.php:36
+msgid "Name of new calendar"
+msgstr ""
+
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr ""
+
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr ""
+
+#: templates/part.import.php:47
+msgid "Import"
+msgstr ""
+
+#: templates/part.import.php:56
+msgid "Close Dialog"
+msgstr ""
+
+#: templates/part.newevent.php:1
+msgid "Create a new event"
+msgstr ""
+
+#: templates/part.showevent.php:1
+msgid "View an event"
+msgstr ""
+
+#: templates/part.showevent.php:23
+msgid "No categories selected"
+msgstr ""
+
+#: templates/part.showevent.php:37
+msgid "of"
+msgstr ""
+
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
+msgid "at"
+msgstr ""
+
+#: templates/settings.php:14
+msgid "Timezone"
+msgstr ""
+
+#: templates/settings.php:31
+msgid "Check always for changes of the timezone"
+msgstr ""
+
+#: templates/settings.php:33
+msgid "Timeformat"
+msgstr ""
+
+#: templates/settings.php:35
+msgid "24h"
+msgstr ""
+
+#: templates/settings.php:36
+msgid "12h"
+msgstr ""
+
+#: templates/settings.php:40
+msgid "First day of the week"
+msgstr ""
+
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr ""
+
+#: templates/share.dropdown.php:20
+msgid "Users"
+msgstr ""
+
+#: templates/share.dropdown.php:21
+msgid "select users"
+msgstr ""
+
+#: templates/share.dropdown.php:36 templates/share.dropdown.php:62
+msgid "Editable"
+msgstr ""
+
+#: templates/share.dropdown.php:48
+msgid "Groups"
+msgstr ""
+
+#: templates/share.dropdown.php:49
+msgid "select groups"
+msgstr ""
+
+#: templates/share.dropdown.php:75
+msgid "make public"
+msgstr ""
diff --git a/l10n/id_ID/contacts.po b/l10n/id_ID/contacts.po
new file mode 100644
index 00000000000..6bbcb889ca0
--- /dev/null
+++ b/l10n/id_ID/contacts.po
@@ -0,0 +1,871 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
+msgid "Error (de)activating addressbook."
+msgstr ""
+
+#: ajax/addcontact.php:47
+msgid "There was an error adding the contact."
+msgstr ""
+
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr ""
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr ""
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr ""
+
+#: ajax/addproperty.php:56
+msgid "Cannot add empty property."
+msgstr ""
+
+#: ajax/addproperty.php:67
+msgid "At least one of the address fields has to be filled out."
+msgstr ""
+
+#: ajax/addproperty.php:76
+msgid "Trying to add duplicate property: "
+msgstr ""
+
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:17
+msgid "No ID provided"
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:34
+msgid "Error setting checksum."
+msgstr ""
+
+#: ajax/categories/delete.php:19
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: ajax/categories/delete.php:26
+msgid "No address books found."
+msgstr ""
+
+#: ajax/categories/delete.php:34
+msgid "No contacts found."
+msgstr ""
+
+#: ajax/contactdetails.php:31
+msgid "Missing ID"
+msgstr ""
+
+#: ajax/contactdetails.php:36
+msgid "Error parsing VCard for ID: \""
+msgstr ""
+
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
+#: ajax/uploadphoto.php:68
+msgid "No contact ID was submitted."
+msgstr ""
+
+#: ajax/currentphoto.php:36
+msgid "Error reading contact photo."
+msgstr ""
+
+#: ajax/currentphoto.php:48
+msgid "Error saving temporary file."
+msgstr ""
+
+#: ajax/currentphoto.php:51
+msgid "The loading photo is not valid."
+msgstr ""
+
+#: ajax/deleteproperty.php:36
+msgid "Information about vCard is incorrect. Please reload the page."
+msgstr ""
+
+#: ajax/deleteproperty.php:43
+msgid "Error deleting contact property."
+msgstr ""
+
+#: ajax/editname.php:31
+msgid "Contact ID is missing."
+msgstr ""
+
+#: ajax/oc_photo.php:32
+msgid "No photo path was submitted."
+msgstr ""
+
+#: ajax/oc_photo.php:39
+msgid "File doesn't exist:"
+msgstr ""
+
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
+msgid "Error loading image."
+msgstr ""
+
+#: ajax/savecrop.php:67
+msgid "Error getting contact object."
+msgstr ""
+
+#: ajax/savecrop.php:76
+msgid "Error getting PHOTO property."
+msgstr ""
+
+#: ajax/savecrop.php:93
+msgid "Error saving contact."
+msgstr ""
+
+#: ajax/savecrop.php:103
+msgid "Error resizing image"
+msgstr ""
+
+#: ajax/savecrop.php:106
+msgid "Error cropping image"
+msgstr ""
+
+#: ajax/savecrop.php:109
+msgid "Error creating temporary image"
+msgstr ""
+
+#: ajax/savecrop.php:112
+msgid "Error finding image: "
+msgstr ""
+
+#: ajax/saveproperty.php:40
+msgid "checksum is not set."
+msgstr ""
+
+#: ajax/saveproperty.php:59
+msgid "Information about vCard is incorrect. Please reload the page: "
+msgstr ""
+
+#: ajax/saveproperty.php:64
+msgid "Something went FUBAR. "
+msgstr ""
+
+#: ajax/saveproperty.php:133
+msgid "Error updating contact property."
+msgstr ""
+
+#: ajax/updateaddressbook.php:21
+msgid "Cannot update addressbook with an empty name."
+msgstr ""
+
+#: ajax/updateaddressbook.php:25
+msgid "Error updating addressbook."
+msgstr ""
+
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
+msgid "Error uploading contacts to storage."
+msgstr ""
+
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
+msgid "Couldn't save temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
+msgid "Couldn't load temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:71
+msgid "No file was uploaded. Unknown error"
+msgstr ""
+
+#: appinfo/app.php:19 templates/settings.php:3
+msgid "Contacts"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Sorry, this functionality has not been implemented yet"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Not implemented"
+msgstr ""
+
+#: js/contacts.js:58
+msgid "Couldn't get a valid address."
+msgstr ""
+
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
+msgid "Error"
+msgstr ""
+
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New Contact"
+msgstr ""
+
+#: js/contacts.js:691
+msgid "This property has to be non-empty."
+msgstr ""
+
+#: js/contacts.js:717
+msgid "Couldn't serialize elements."
+msgstr ""
+
+#: js/contacts.js:826 js/contacts.js:844
+msgid ""
+"'deleteProperty' called without type argument. Please report at "
+"bugs.owncloud.org"
+msgstr ""
+
+#: js/contacts.js:860
+msgid "Edit name"
+msgstr ""
+
+#: js/contacts.js:1141
+msgid "No files selected for upload."
+msgstr ""
+
+#: js/contacts.js:1149
+msgid ""
+"The file you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: js/contacts.js:1314 js/contacts.js:1348
+msgid "Select type"
+msgstr ""
+
+#: js/loader.js:49
+msgid "Result: "
+msgstr ""
+
+#: js/loader.js:49
+msgid " imported, "
+msgstr ""
+
+#: js/loader.js:49
+msgid " failed."
+msgstr ""
+
+#: lib/app.php:29
+msgid "Addressbook not found."
+msgstr ""
+
+#: lib/app.php:33
+msgid "This is not your addressbook."
+msgstr ""
+
+#: lib/app.php:44
+msgid "Contact could not be found."
+msgstr ""
+
+#: lib/app.php:100 templates/part.contact.php:116
+msgid "Address"
+msgstr ""
+
+#: lib/app.php:101
+msgid "Telephone"
+msgstr ""
+
+#: lib/app.php:102 templates/part.contact.php:115
+msgid "Email"
+msgstr ""
+
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
+msgid "Organization"
+msgstr ""
+
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
+msgid "Home"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Mobile"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Text"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Voice"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Message"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Fax"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Video"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Pager"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Internet"
+msgstr ""
+
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:170
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:171
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:172
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:179
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr ""
+
+#: lib/hooks.php:102
+msgid "{name}'s Birthday"
+msgstr ""
+
+#: templates/index.php:15
+msgid "Add Contact"
+msgstr ""
+
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr ""
+
+#: templates/index.php:20
+msgid "Addressbooks"
+msgstr ""
+
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr ""
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr ""
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr ""
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr ""
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr ""
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr ""
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr ""
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr ""
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr ""
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:1
+msgid "Configure Address Books"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:16
+msgid "New Address Book"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:21
+#: templates/part.chooseaddressbook.rowfields.php:8
+msgid "CardDav Link"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:11
+msgid "Download"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:14
+msgid "Edit"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:17
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
+msgid "Delete"
+msgstr ""
+
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
+msgstr ""
+
+#: templates/part.contact.php:18
+msgid "Delete current photo"
+msgstr ""
+
+#: templates/part.contact.php:19
+msgid "Edit current photo"
+msgstr ""
+
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr ""
+
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr ""
+
+#: templates/part.contact.php:34
+msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
+msgstr ""
+
+#: templates/part.contact.php:35
+msgid "Edit name details"
+msgstr ""
+
+#: templates/part.contact.php:40 templates/part.contact.php:112
+msgid "Nickname"
+msgstr ""
+
+#: templates/part.contact.php:41
+msgid "Enter nickname"
+msgstr ""
+
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr ""
+
+#: templates/part.contact.php:45
+msgid "dd-mm-yyyy"
+msgstr ""
+
+#: templates/part.contact.php:46 templates/part.contact.php:119
+msgid "Groups"
+msgstr ""
+
+#: templates/part.contact.php:48
+msgid "Separate groups with commas"
+msgstr ""
+
+#: templates/part.contact.php:49
+msgid "Edit groups"
+msgstr ""
+
+#: templates/part.contact.php:62 templates/part.contact.php:76
+msgid "Preferred"
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Please specify a valid email address."
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Enter email address"
+msgstr ""
+
+#: templates/part.contact.php:67
+msgid "Mail to address"
+msgstr ""
+
+#: templates/part.contact.php:68
+msgid "Delete email address"
+msgstr ""
+
+#: templates/part.contact.php:77
+msgid "Enter phone number"
+msgstr ""
+
+#: templates/part.contact.php:81
+msgid "Delete phone number"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "View on map"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "Edit address details"
+msgstr ""
+
+#: templates/part.contact.php:102
+msgid "Add notes here."
+msgstr ""
+
+#: templates/part.contact.php:109
+msgid "Add field"
+msgstr ""
+
+#: templates/part.contact.php:114
+msgid "Phone"
+msgstr ""
+
+#: templates/part.contact.php:117
+msgid "Note"
+msgstr ""
+
+#: templates/part.contact.php:122
+msgid "Download contact"
+msgstr ""
+
+#: templates/part.contact.php:123
+msgid "Delete contact"
+msgstr ""
+
+#: templates/part.cropphoto.php:65
+msgid "The temporary image has been removed from cache."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:6
+msgid "Edit address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:10
+msgid "Type"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
+msgid "PO Box"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:30
+msgid "Extended"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
+msgid "City"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:42
+msgid "Region"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:48
+msgid "Zipcode"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
+msgid "Country"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:16
+msgid "Addressbook"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:23
+msgid "Hon. prefixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:27
+msgid "Miss"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:28
+msgid "Ms"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:29
+msgid "Mr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:30
+msgid "Sir"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:31
+msgid "Mrs"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:32
+msgid "Dr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:35
+msgid "Given name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:37
+msgid "Additional names"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:39
+msgid "Family name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:41
+msgid "Hon. suffixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:45
+msgid "J.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:46
+msgid "M.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:47
+msgid "D.O."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:48
+msgid "D.C."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:49
+msgid "Ph.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:50
+msgid "Esq."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:51
+msgid "Jr."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:52
+msgid "Sn."
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "New Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "Edit Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editaddressbook.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Save"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editaddressbook.php:30
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.import.php:1
+msgid "Import a contacts file"
+msgstr ""
+
+#: templates/part.import.php:6
+msgid "Please choose the addressbook"
+msgstr ""
+
+#: templates/part.import.php:10
+msgid "create a new addressbook"
+msgstr ""
+
+#: templates/part.import.php:15
+msgid "Name of new addressbook"
+msgstr ""
+
+#: templates/part.import.php:20
+msgid "Importing contacts"
+msgstr ""
+
+#: templates/part.no_contacts.php:2
+msgid "You have no contacts in your addressbook."
+msgstr ""
+
+#: templates/part.no_contacts.php:4
+msgid "Add contact"
+msgstr ""
+
+#: templates/part.no_contacts.php:5
+msgid "Configure addressbooks"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "CardDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:6
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:8
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr ""
diff --git a/l10n/id_ID/core.po b/l10n/id_ID/core.po
new file mode 100644
index 00000000000..2a3c3b516c8
--- /dev/null
+++ b/l10n/id_ID/core.po
@@ -0,0 +1,268 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:28+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/vcategories/add.php:23 ajax/vcategories/delete.php:23
+msgid "Application name not provided."
+msgstr ""
+
+#: ajax/vcategories/add.php:29
+msgid "No category to add?"
+msgstr ""
+
+#: ajax/vcategories/add.php:36
+msgid "This category already exists: "
+msgstr ""
+
+#: js/jquery-ui-1.8.16.custom.min.js:511
+msgid "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
+msgstr ""
+
+#: js/js.js:519
+msgid "January"
+msgstr ""
+
+#: js/js.js:519
+msgid "February"
+msgstr ""
+
+#: js/js.js:519
+msgid "March"
+msgstr ""
+
+#: js/js.js:519
+msgid "April"
+msgstr ""
+
+#: js/js.js:519
+msgid "May"
+msgstr ""
+
+#: js/js.js:519
+msgid "June"
+msgstr ""
+
+#: js/js.js:520
+msgid "July"
+msgstr ""
+
+#: js/js.js:520
+msgid "August"
+msgstr ""
+
+#: js/js.js:520
+msgid "September"
+msgstr ""
+
+#: js/js.js:520
+msgid "October"
+msgstr ""
+
+#: js/js.js:520
+msgid "November"
+msgstr ""
+
+#: js/js.js:520
+msgid "December"
+msgstr ""
+
+#: js/oc-dialogs.js:143 js/oc-dialogs.js:163
+msgid "Cancel"
+msgstr ""
+
+#: js/oc-dialogs.js:159
+msgid "No"
+msgstr ""
+
+#: js/oc-dialogs.js:160
+msgid "Yes"
+msgstr ""
+
+#: js/oc-dialogs.js:177
+msgid "Ok"
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "Error"
+msgstr ""
+
+#: lostpassword/index.php:26
+msgid "ownCloud password reset"
+msgstr ""
+
+#: lostpassword/templates/email.php:1
+msgid "Use the following link to reset your password: {link}"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:3
+msgid "You will receive a link to reset your password via Email."
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:5
+msgid "Requested"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:8
+msgid "Login failed!"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:11 templates/installation.php:25
+#: templates/login.php:9
+msgid "Username"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:15
+msgid "Request reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:4
+msgid "Your password was reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:5
+msgid "To login page"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:8
+msgid "New password"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:11
+msgid "Reset password"
+msgstr ""
+
+#: strings.php:5
+msgid "Personal"
+msgstr ""
+
+#: strings.php:6
+msgid "Users"
+msgstr ""
+
+#: strings.php:7
+msgid "Apps"
+msgstr ""
+
+#: strings.php:8
+msgid "Admin"
+msgstr ""
+
+#: strings.php:9
+msgid "Help"
+msgstr ""
+
+#: templates/403.php:12
+msgid "Access forbidden"
+msgstr ""
+
+#: templates/404.php:12
+msgid "Cloud not found"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:4
+msgid "Edit categories"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:14
+msgid "Add"
+msgstr ""
+
+#: templates/installation.php:23
+msgid "Create an <strong>admin account</strong>"
+msgstr ""
+
+#: templates/installation.php:29 templates/login.php:13
+msgid "Password"
+msgstr ""
+
+#: templates/installation.php:35
+msgid "Advanced"
+msgstr ""
+
+#: templates/installation.php:37
+msgid "Data folder"
+msgstr ""
+
+#: templates/installation.php:44
+msgid "Configure the database"
+msgstr ""
+
+#: templates/installation.php:49 templates/installation.php:60
+#: templates/installation.php:70
+msgid "will be used"
+msgstr ""
+
+#: templates/installation.php:82
+msgid "Database user"
+msgstr ""
+
+#: templates/installation.php:86
+msgid "Database password"
+msgstr ""
+
+#: templates/installation.php:90
+msgid "Database name"
+msgstr ""
+
+#: templates/installation.php:96
+msgid "Database host"
+msgstr ""
+
+#: templates/installation.php:101
+msgid "Finish setup"
+msgstr ""
+
+#: templates/layout.guest.php:42
+msgid "web services under your control"
+msgstr ""
+
+#: templates/layout.user.php:49
+msgid "Log out"
+msgstr ""
+
+#: templates/layout.user.php:64 templates/layout.user.php:65
+msgid "Settings"
+msgstr ""
+
+#: templates/login.php:6
+msgid "Lost your password?"
+msgstr ""
+
+#: templates/login.php:17
+msgid "remember"
+msgstr ""
+
+#: templates/login.php:18
+msgid "Log in"
+msgstr ""
+
+#: templates/logout.php:1
+msgid "You are logged out."
+msgstr ""
+
+#: templates/part.pagenavi.php:3
+msgid "prev"
+msgstr ""
+
+#: templates/part.pagenavi.php:20
+msgid "next"
+msgstr ""
diff --git a/l10n/id_ID/files.po b/l10n/id_ID/files.po
new file mode 100644
index 00000000000..6fc758f5962
--- /dev/null
+++ b/l10n/id_ID/files.po
@@ -0,0 +1,198 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/upload.php:20
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/upload.php:21
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/upload.php:22
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/upload.php:23
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/upload.php:24
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/upload.php:25
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/upload.php:26
+msgid "Failed to write to disk"
+msgstr ""
+
+#: appinfo/app.php:6
+msgid "Files"
+msgstr ""
+
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr ""
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr ""
+
+#: js/filelist.js:186
+msgid "undo deletion"
+msgstr ""
+
+#: js/files.js:170
+msgid "generating ZIP-file, it may take some time."
+msgstr ""
+
+#: js/files.js:199
+msgid "Unable to upload your file as it is a directory or has 0 bytes"
+msgstr ""
+
+#: js/files.js:199
+msgid "Upload Error"
+msgstr ""
+
+#: js/files.js:227 js/files.js:318 js/files.js:347
+msgid "Pending"
+msgstr ""
+
+#: js/files.js:332
+msgid "Upload cancelled."
+msgstr ""
+
+#: js/files.js:456
+msgid "Invalid name, '/' is not allowed."
+msgstr ""
+
+#: js/files.js:631 templates/index.php:55
+msgid "Size"
+msgstr ""
+
+#: js/files.js:632 templates/index.php:56
+msgid "Modified"
+msgstr ""
+
+#: js/files.js:659
+msgid "folder"
+msgstr ""
+
+#: js/files.js:661
+msgid "folders"
+msgstr ""
+
+#: js/files.js:669
+msgid "file"
+msgstr ""
+
+#: js/files.js:671
+msgid "files"
+msgstr ""
+
+#: templates/admin.php:5
+msgid "File handling"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "Maximum upload size"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "max. possible: "
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Needed for multi-file and folder downloads."
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Enable ZIP-download"
+msgstr ""
+
+#: templates/admin.php:11
+msgid "0 is unlimited"
+msgstr ""
+
+#: templates/admin.php:12
+msgid "Maximum input size for ZIP files"
+msgstr ""
+
+#: templates/index.php:7
+msgid "New"
+msgstr ""
+
+#: templates/index.php:9
+msgid "Text file"
+msgstr ""
+
+#: templates/index.php:10
+msgid "Folder"
+msgstr ""
+
+#: templates/index.php:11
+msgid "From url"
+msgstr ""
+
+#: templates/index.php:21
+msgid "Upload"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Cancel upload"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Nothing in here. Upload something!"
+msgstr ""
+
+#: templates/index.php:47
+msgid "Name"
+msgstr ""
+
+#: templates/index.php:49
+msgid "Share"
+msgstr ""
+
+#: templates/index.php:51
+msgid "Download"
+msgstr ""
+
+#: templates/index.php:64
+msgid "Upload too large"
+msgstr ""
+
+#: templates/index.php:66
+msgid ""
+"The files you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: templates/index.php:71
+msgid "Files are being scanned, please wait."
+msgstr ""
+
+#: templates/index.php:74
+msgid "Current scanning"
+msgstr ""
diff --git a/l10n/id_ID/gallery.po b/l10n/id_ID/gallery.po
new file mode 100644
index 00000000000..6d62fde891d
--- /dev/null
+++ b/l10n/id_ID/gallery.po
@@ -0,0 +1,58 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: appinfo/app.php:39
+msgid "Pictures"
+msgstr ""
+
+#: js/pictures.js:12
+msgid "Share gallery"
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Error: "
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Internal error"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr ""
+
+#: templates/view_album.php:19
+msgid "Back"
+msgstr ""
+
+#: templates/view_album.php:36
+msgid "Remove confirmation"
+msgstr ""
+
+#: templates/view_album.php:37
+msgid "Do you want to remove album"
+msgstr ""
+
+#: templates/view_album.php:40
+msgid "Change album name"
+msgstr ""
+
+#: templates/view_album.php:43
+msgid "New album name"
+msgstr ""
diff --git a/l10n/id_ID/media.po b/l10n/id_ID/media.po
new file mode 100644
index 00000000000..1db3e2f400f
--- /dev/null
+++ b/l10n/id_ID/media.po
@@ -0,0 +1,66 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2011-08-13 02:19+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: appinfo/app.php:45 templates/player.php:8
+msgid "Music"
+msgstr ""
+
+#: js/music.js:18
+msgid "Add album to playlist"
+msgstr ""
+
+#: templates/music.php:3 templates/player.php:12
+msgid "Play"
+msgstr ""
+
+#: templates/music.php:4 templates/music.php:26 templates/player.php:13
+msgid "Pause"
+msgstr ""
+
+#: templates/music.php:5
+msgid "Previous"
+msgstr ""
+
+#: templates/music.php:6 templates/player.php:14
+msgid "Next"
+msgstr ""
+
+#: templates/music.php:7
+msgid "Mute"
+msgstr ""
+
+#: templates/music.php:8
+msgid "Unmute"
+msgstr ""
+
+#: templates/music.php:25
+msgid "Rescan Collection"
+msgstr ""
+
+#: templates/music.php:37
+msgid "Artist"
+msgstr ""
+
+#: templates/music.php:38
+msgid "Album"
+msgstr ""
+
+#: templates/music.php:39
+msgid "Title"
+msgstr ""
diff --git a/l10n/id_ID/settings.po b/l10n/id_ID/settings.po
new file mode 100644
index 00000000000..ec3c94d41f9
--- /dev/null
+++ b/l10n/id_ID/settings.po
@@ -0,0 +1,206 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Indonesian (Indonesia) (http://www.transifex.com/projects/p/owncloud/language/id_ID/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id_ID\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/lostpassword.php:14
+msgid "Email saved"
+msgstr ""
+
+#: ajax/lostpassword.php:16
+msgid "Invalid email"
+msgstr ""
+
+#: ajax/openid.php:16
+msgid "OpenID Changed"
+msgstr ""
+
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
+msgid "Invalid request"
+msgstr ""
+
+#: ajax/setlanguage.php:18
+msgid "Language changed"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:67
+msgid "Disable"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:54
+msgid "Enable"
+msgstr ""
+
+#: js/personal.js:69
+msgid "Saving..."
+msgstr ""
+
+#: personal.php:41 personal.php:42
+msgid "__language_name__"
+msgstr ""
+
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr ""
+
+#: templates/admin.php:28
+msgid "Log"
+msgstr ""
+
+#: templates/admin.php:55
+msgid "More"
+msgstr ""
+
+#: templates/apps.php:10
+msgid "Add your App"
+msgstr ""
+
+#: templates/apps.php:24
+msgid "Select an App"
+msgstr ""
+
+#: templates/apps.php:27
+msgid "See application page at apps.owncloud.com"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "-licensed"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "by"
+msgstr ""
+
+#: templates/help.php:8
+msgid "Documentation"
+msgstr ""
+
+#: templates/help.php:9
+msgid "Managing Big Files"
+msgstr ""
+
+#: templates/help.php:10
+msgid "Ask a question"
+msgstr ""
+
+#: templates/help.php:22
+msgid "Problems connecting to help database."
+msgstr ""
+
+#: templates/help.php:23
+msgid "Go there manually."
+msgstr ""
+
+#: templates/help.php:31
+msgid "Answer"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "You use"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "of the available"
+msgstr ""
+
+#: templates/personal.php:12
+msgid "Desktop and Mobile Syncing Clients"
+msgstr ""
+
+#: templates/personal.php:13
+msgid "Download"
+msgstr ""
+
+#: templates/personal.php:19
+msgid "Your password got changed"
+msgstr ""
+
+#: templates/personal.php:20
+msgid "Unable to change your password"
+msgstr ""
+
+#: templates/personal.php:21
+msgid "Current password"
+msgstr ""
+
+#: templates/personal.php:22
+msgid "New password"
+msgstr ""
+
+#: templates/personal.php:23
+msgid "show"
+msgstr ""
+
+#: templates/personal.php:24
+msgid "Change password"
+msgstr ""
+
+#: templates/personal.php:30
+msgid "Email"
+msgstr ""
+
+#: templates/personal.php:31
+msgid "Your email address"
+msgstr ""
+
+#: templates/personal.php:32
+msgid "Fill in an email address to enable password recovery"
+msgstr ""
+
+#: templates/personal.php:38 templates/personal.php:39
+msgid "Language"
+msgstr ""
+
+#: templates/personal.php:44
+msgid "Help translate"
+msgstr ""
+
+#: templates/personal.php:51
+msgid "use this address to connect to your ownCloud in your file manager"
+msgstr ""
+
+#: templates/users.php:15 templates/users.php:60
+msgid "Name"
+msgstr ""
+
+#: templates/users.php:17 templates/users.php:61
+msgid "Password"
+msgstr ""
+
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
+msgid "Groups"
+msgstr ""
+
+#: templates/users.php:25
+msgid "Create"
+msgstr ""
+
+#: templates/users.php:28
+msgid "Default Quota"
+msgstr ""
+
+#: templates/users.php:47 templates/users.php:103
+msgid "Other"
+msgstr ""
+
+#: templates/users.php:63
+msgid "Quota"
+msgstr ""
+
+#: templates/users.php:110
+msgid "Delete"
+msgstr ""
diff --git a/l10n/it/calendar.po b/l10n/it/calendar.po
index ed36e36d84c..67fa300db84 100644
--- a/l10n/it/calendar.po
+++ b/l10n/it/calendar.po
@@ -15,21 +15,29 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:14+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Italian (http://www.transifex.net/projects/p/owncloud/language/it/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 20:45+0000\n"
+"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ajax/categories/rescan.php:28
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr "Non tutti i calendari sono mantenuti completamente in cache"
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr "Tutto sembra essere mantenuto completamente in cache"
+
+#: ajax/categories/rescan.php:29
msgid "No calendars found."
msgstr "Nessun calendario trovato."
-#: ajax/categories/rescan.php:36
+#: ajax/categories/rescan.php:37
msgid "No events found."
msgstr "Nessun evento trovato."
@@ -37,43 +45,57 @@ msgstr "Nessun evento trovato."
msgid "Wrong calendar"
msgstr "Calendario sbagliato"
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr "Il file non conteneva alcun evento o tutti gli eventi erano già salvati nel tuo calendario."
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr "gli eventi sono stati salvati nel nuovo calendario"
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr "Importazione non riuscita"
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr "gli eventi sono stati salvati nel tuo calendario"
+
#: ajax/settings/guesstimezone.php:25
msgid "New Timezone:"
msgstr "Nuovo fuso orario:"
-#: ajax/settings/settimezone.php:22
+#: ajax/settings/settimezone.php:23
msgid "Timezone changed"
msgstr "Fuso orario cambiato"
-#: ajax/settings/settimezone.php:24
+#: ajax/settings/settimezone.php:25
msgid "Invalid request"
msgstr "Richiesta non valida"
-#: appinfo/app.php:19 templates/calendar.php:15
-#: templates/part.eventform.php:33 templates/part.showevent.php:31
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
#: templates/settings.php:12
msgid "Calendar"
msgstr "Calendario"
-#: js/calendar.js:93
-msgid "Deletion failed"
-msgstr ""
-
#: js/calendar.js:828
msgid "ddd"
-msgstr ""
+msgstr "ggg"
#: js/calendar.js:829
msgid "ddd M/d"
-msgstr ""
+msgstr "ggg M/g"
#: js/calendar.js:830
msgid "dddd M/d"
-msgstr ""
+msgstr "gggg M/g"
#: js/calendar.js:833
msgid "MMMM yyyy"
-msgstr ""
+msgstr "MMMM aaaa"
#: js/calendar.js:835
msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
@@ -81,256 +103,337 @@ msgstr "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
#: js/calendar.js:837
msgid "dddd, MMM d, yyyy"
-msgstr ""
+msgstr "gggg, MMM g, aaaa"
-#: lib/app.php:125
+#: lib/app.php:121
msgid "Birthday"
msgstr "Compleanno"
-#: lib/app.php:126
+#: lib/app.php:122
msgid "Business"
msgstr "Azienda"
-#: lib/app.php:127
+#: lib/app.php:123
msgid "Call"
msgstr "Chiama"
-#: lib/app.php:128
+#: lib/app.php:124
msgid "Clients"
msgstr "Clienti"
-#: lib/app.php:129
+#: lib/app.php:125
msgid "Deliverer"
msgstr "Consegna"
-#: lib/app.php:130
+#: lib/app.php:126
msgid "Holidays"
msgstr "Vacanze"
-#: lib/app.php:131
+#: lib/app.php:127
msgid "Ideas"
msgstr "Idee"
-#: lib/app.php:132
+#: lib/app.php:128
msgid "Journey"
msgstr "Viaggio"
-#: lib/app.php:133
+#: lib/app.php:129
msgid "Jubilee"
msgstr "Anniversario"
-#: lib/app.php:134
+#: lib/app.php:130
msgid "Meeting"
msgstr "Riunione"
-#: lib/app.php:135
+#: lib/app.php:131
msgid "Other"
msgstr "Altro"
-#: lib/app.php:136
+#: lib/app.php:132
msgid "Personal"
msgstr "Personale"
-#: lib/app.php:137
+#: lib/app.php:133
msgid "Projects"
msgstr "Progetti"
-#: lib/app.php:138
+#: lib/app.php:134
msgid "Questions"
msgstr "Domande"
-#: lib/app.php:139
+#: lib/app.php:135
msgid "Work"
msgstr "Lavoro"
-#: lib/app.php:380
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr "da"
+
+#: lib/app.php:359 lib/app.php:399
msgid "unnamed"
msgstr "senza nome"
-#: lib/object.php:330
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr "Nuovo calendario"
+
+#: lib/object.php:372
msgid "Does not repeat"
msgstr "Non ripetere"
-#: lib/object.php:331
+#: lib/object.php:373
msgid "Daily"
msgstr "Giornaliero"
-#: lib/object.php:332
+#: lib/object.php:374
msgid "Weekly"
msgstr "Settimanale"
-#: lib/object.php:333
+#: lib/object.php:375
msgid "Every Weekday"
msgstr "Ogni giorno della settimana"
-#: lib/object.php:334
+#: lib/object.php:376
msgid "Bi-Weekly"
msgstr "Ogni due settimane"
-#: lib/object.php:335
+#: lib/object.php:377
msgid "Monthly"
msgstr "Mensile"
-#: lib/object.php:336
+#: lib/object.php:378
msgid "Yearly"
msgstr "Annuale"
-#: lib/object.php:343
+#: lib/object.php:388
msgid "never"
msgstr "mai"
-#: lib/object.php:344
+#: lib/object.php:389
msgid "by occurrences"
msgstr "per occorrenze"
-#: lib/object.php:345
+#: lib/object.php:390
msgid "by date"
msgstr "per data"
-#: lib/object.php:352
+#: lib/object.php:400
msgid "by monthday"
msgstr "per giorno del mese"
-#: lib/object.php:353
+#: lib/object.php:401
msgid "by weekday"
msgstr "per giorno della settimana"
-#: lib/object.php:360 templates/settings.php:42
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
msgid "Monday"
msgstr "Lunedì"
-#: lib/object.php:361
+#: lib/object.php:412 templates/calendar.php:5
msgid "Tuesday"
msgstr "Martedì"
-#: lib/object.php:362
+#: lib/object.php:413 templates/calendar.php:5
msgid "Wednesday"
msgstr "Mercoledì"
-#: lib/object.php:363
+#: lib/object.php:414 templates/calendar.php:5
msgid "Thursday"
msgstr "Giovedì"
-#: lib/object.php:364
+#: lib/object.php:415 templates/calendar.php:5
msgid "Friday"
msgstr "Venerdì"
-#: lib/object.php:365
+#: lib/object.php:416 templates/calendar.php:5
msgid "Saturday"
msgstr "Sabato"
-#: lib/object.php:366 templates/settings.php:43
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
msgid "Sunday"
msgstr "Domenica"
-#: lib/object.php:373
+#: lib/object.php:427
msgid "events week of month"
msgstr "settimana del mese degli eventi"
-#: lib/object.php:374
+#: lib/object.php:428
msgid "first"
msgstr "primo"
-#: lib/object.php:375
+#: lib/object.php:429
msgid "second"
msgstr "secondo"
-#: lib/object.php:376
+#: lib/object.php:430
msgid "third"
msgstr "terzo"
-#: lib/object.php:377
+#: lib/object.php:431
msgid "fourth"
msgstr "quarto"
-#: lib/object.php:378
+#: lib/object.php:432
msgid "fifth"
msgstr "quinto"
-#: lib/object.php:379
+#: lib/object.php:433
msgid "last"
msgstr "ultimo"
-#: lib/object.php:401
+#: lib/object.php:467 templates/calendar.php:7
msgid "January"
msgstr "Gennaio"
-#: lib/object.php:402
+#: lib/object.php:468 templates/calendar.php:7
msgid "February"
msgstr "Febbraio"
-#: lib/object.php:403
+#: lib/object.php:469 templates/calendar.php:7
msgid "March"
msgstr "Marzo"
-#: lib/object.php:404
+#: lib/object.php:470 templates/calendar.php:7
msgid "April"
msgstr "Aprile"
-#: lib/object.php:405
+#: lib/object.php:471 templates/calendar.php:7
msgid "May"
msgstr "Maggio"
-#: lib/object.php:406
+#: lib/object.php:472 templates/calendar.php:7
msgid "June"
msgstr "Giugno"
-#: lib/object.php:407
+#: lib/object.php:473 templates/calendar.php:7
msgid "July"
msgstr "Luglio"
-#: lib/object.php:408
+#: lib/object.php:474 templates/calendar.php:7
msgid "August"
msgstr "Agosto"
-#: lib/object.php:409
+#: lib/object.php:475 templates/calendar.php:7
msgid "September"
msgstr "Settembre"
-#: lib/object.php:410
+#: lib/object.php:476 templates/calendar.php:7
msgid "October"
msgstr "Ottobre"
-#: lib/object.php:411
+#: lib/object.php:477 templates/calendar.php:7
msgid "November"
msgstr "Novembre"
-#: lib/object.php:412
+#: lib/object.php:478 templates/calendar.php:7
msgid "December"
msgstr "Dicembre"
-#: lib/object.php:418
+#: lib/object.php:488
msgid "by events date"
msgstr "per data evento"
-#: lib/object.php:419
+#: lib/object.php:489
msgid "by yearday(s)"
msgstr "per giorno/i dell'anno"
-#: lib/object.php:420
+#: lib/object.php:490
msgid "by weeknumber(s)"
msgstr "per numero/i settimana"
-#: lib/object.php:421
+#: lib/object.php:491
msgid "by day and month"
msgstr "per giorno e mese"
-#: lib/search.php:32 lib/search.php:34 lib/search.php:37
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
msgid "Date"
msgstr "Data"
-#: lib/search.php:40
+#: lib/search.php:43
msgid "Cal."
msgstr "Cal."
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr "Dom."
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr "Lun."
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr "Mar."
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr "Mer."
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr "Gio."
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr "Ven."
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr "Sab."
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr "Gen."
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr "Feb."
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr "Mar."
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr "Apr."
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr "Mag."
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr "Giu."
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr "Lug."
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr "Ago."
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr "Set."
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr "Ott."
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr "Nov."
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr "Dic."
+
#: templates/calendar.php:11
msgid "All day"
msgstr "Tutti il giorno"
-#: templates/calendar.php:12 templates/part.choosecalendar.php:22
-msgid "New Calendar"
-msgstr "Nuovo calendario"
-
#: templates/calendar.php:13
msgid "Missing fields"
msgstr "Campi mancanti"
@@ -364,27 +467,27 @@ msgstr "L'evento finisce prima d'iniziare"
msgid "There was a database fail"
msgstr "Si è verificato un errore del database"
-#: templates/calendar.php:40
+#: templates/calendar.php:38
msgid "Week"
msgstr "Settimana"
-#: templates/calendar.php:41
+#: templates/calendar.php:39
msgid "Month"
msgstr "Mese"
-#: templates/calendar.php:42
+#: templates/calendar.php:40
msgid "List"
msgstr "Elenco"
-#: templates/calendar.php:48
+#: templates/calendar.php:44
msgid "Today"
msgstr "Oggi"
-#: templates/calendar.php:49
+#: templates/calendar.php:45
msgid "Calendars"
msgstr "Calendari"
-#: templates/calendar.php:67
+#: templates/calendar.php:59
msgid "There was a fail, while parsing the file."
msgstr "Si è verificato un errore durante l'analisi del file."
@@ -397,7 +500,7 @@ msgid "Your calendars"
msgstr "I tuoi calendari"
#: templates/part.choosecalendar.php:27
-#: templates/part.choosecalendar.rowfields.php:5
+#: templates/part.choosecalendar.rowfields.php:11
msgid "CalDav Link"
msgstr "Collegamento CalDav"
@@ -409,19 +512,19 @@ msgstr "Calendari condivisi"
msgid "No shared calendars"
msgstr "Nessun calendario condiviso"
-#: templates/part.choosecalendar.rowfields.php:4
+#: templates/part.choosecalendar.rowfields.php:8
msgid "Share Calendar"
msgstr "Condividi calendario"
-#: templates/part.choosecalendar.rowfields.php:6
+#: templates/part.choosecalendar.rowfields.php:14
msgid "Download"
msgstr "Scarica"
-#: templates/part.choosecalendar.rowfields.php:7
+#: templates/part.choosecalendar.rowfields.php:17
msgid "Edit"
msgstr "Modifica"
-#: templates/part.choosecalendar.rowfields.php:8
+#: templates/part.choosecalendar.rowfields.php:20
#: templates/part.editevent.php:9
msgid "Delete"
msgstr "Elimina"
@@ -507,23 +610,23 @@ msgstr "Categorie separate con virgole"
msgid "Edit categories"
msgstr "Modifica le categorie"
-#: templates/part.eventform.php:56 templates/part.showevent.php:55
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
msgid "All Day Event"
msgstr "Evento che occupa tutta la giornata"
-#: templates/part.eventform.php:60 templates/part.showevent.php:59
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
msgid "From"
msgstr "Da"
-#: templates/part.eventform.php:68 templates/part.showevent.php:67
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
msgid "To"
msgstr "A"
-#: templates/part.eventform.php:76 templates/part.showevent.php:75
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
msgid "Advanced options"
msgstr "Opzioni avanzate"
-#: templates/part.eventform.php:81 templates/part.showevent.php:80
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
msgid "Location"
msgstr "Luogo"
@@ -531,7 +634,7 @@ msgstr "Luogo"
msgid "Location of the Event"
msgstr "Luogo dell'evento"
-#: templates/part.eventform.php:89 templates/part.showevent.php:88
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
msgid "Description"
msgstr "Descrizione"
@@ -539,84 +642,86 @@ msgstr "Descrizione"
msgid "Description of the Event"
msgstr "Descrizione dell'evento"
-#: templates/part.eventform.php:100 templates/part.showevent.php:98
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
msgid "Repeat"
msgstr "Ripeti"
-#: templates/part.eventform.php:107 templates/part.showevent.php:105
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
msgid "Advanced"
msgstr "Avanzato"
-#: templates/part.eventform.php:151 templates/part.showevent.php:149
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
msgid "Select weekdays"
msgstr "Seleziona i giorni della settimana"
#: templates/part.eventform.php:164 templates/part.eventform.php:177
-#: templates/part.showevent.php:162 templates/part.showevent.php:175
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
msgid "Select days"
msgstr "Seleziona i giorni"
-#: templates/part.eventform.php:169 templates/part.showevent.php:167
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
msgid "and the events day of year."
msgstr "e il giorno dell'anno degli eventi."
-#: templates/part.eventform.php:182 templates/part.showevent.php:180
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
msgid "and the events day of month."
msgstr "e il giorno del mese degli eventi."
-#: templates/part.eventform.php:190 templates/part.showevent.php:188
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
msgid "Select months"
msgstr "Seleziona i mesi"
-#: templates/part.eventform.php:203 templates/part.showevent.php:201
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
msgid "Select weeks"
msgstr "Seleziona le settimane"
-#: templates/part.eventform.php:208 templates/part.showevent.php:206
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
msgid "and the events week of year."
msgstr "e la settimana dell'anno degli eventi."
-#: templates/part.eventform.php:214 templates/part.showevent.php:212
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
msgid "Interval"
msgstr "Intervallo"
-#: templates/part.eventform.php:220 templates/part.showevent.php:218
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
msgid "End"
msgstr "Fine"
-#: templates/part.eventform.php:233 templates/part.showevent.php:231
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
msgid "occurrences"
msgstr "occorrenze"
-#: templates/part.import.php:1
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr "Crea un nuovo calendario"
+
+#: templates/part.import.php:17
msgid "Import a calendar file"
msgstr "Importa un file di calendario"
-#: templates/part.import.php:6
-msgid "Please choose the calendar"
-msgstr "Scegli il calendario"
-
-#: templates/part.import.php:10
-msgid "create a new calendar"
-msgstr "Crea un nuovo calendario"
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr "Scegli un calendario"
-#: templates/part.import.php:15
+#: templates/part.import.php:36
msgid "Name of new calendar"
msgstr "Nome del nuovo calendario"
-#: templates/part.import.php:17
-msgid "Import"
-msgstr "Importa"
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr "Usa un nome disponibile!"
-#: templates/part.import.php:20
-msgid "Importing calendar"
-msgstr "Importazione del calendario in corso"
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr "Un calendario con questo nome esiste già. Se continui, i due calendari saranno uniti."
-#: templates/part.import.php:23
-msgid "Calendar imported successfully"
-msgstr "Calendario importato correttamente"
+#: templates/part.import.php:47
+msgid "Import"
+msgstr "Importa"
-#: templates/part.import.php:24
+#: templates/part.import.php:56
msgid "Close Dialog"
msgstr "Chiudi la finestra di dialogo"
@@ -632,15 +737,11 @@ msgstr "Visualizza un evento"
msgid "No categories selected"
msgstr "Nessuna categoria selezionata"
-#: templates/part.showevent.php:25
-msgid "Select category"
-msgstr "Seleziona una categoria"
-
#: templates/part.showevent.php:37
msgid "of"
msgstr "di"
-#: templates/part.showevent.php:62 templates/part.showevent.php:70
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
msgid "at"
msgstr "alle"
@@ -668,9 +769,33 @@ msgstr "12h"
msgid "First day of the week"
msgstr "Primo giorno della settimana"
-#: templates/settings.php:49
-msgid "Calendar CalDAV syncing address:"
-msgstr "Indirizzo sincronizzazione calendario CalDAV:"
+#: templates/settings.php:47
+msgid "Cache"
+msgstr "Cache"
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr "Cancella gli eventi che si ripetono dalla cache"
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr "Indirizzi di sincronizzazione calendari CalDAV"
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr "ulteriori informazioni"
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr "Indirizzo principale (Kontact e altri)"
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr "iOS/OS X"
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr "Collegamento(i) iCalendar sola lettura"
#: templates/share.dropdown.php:20
msgid "Users"
diff --git a/l10n/it/contacts.po b/l10n/it/contacts.po
index 0e1a62a6f93..64b9e1e0a16 100644
--- a/l10n/it/contacts.po
+++ b/l10n/it/contacts.po
@@ -11,101 +11,97 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:14+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Italian (http://www.transifex.net/projects/p/owncloud/language/it/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 21:17+0000\n"
+"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ajax/activation.php:19 ajax/updateaddressbook.php:32
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
msgid "Error (de)activating addressbook."
msgstr "Errore nel (dis)attivare la rubrica."
-#: ajax/addcontact.php:59
+#: ajax/addcontact.php:47
msgid "There was an error adding the contact."
msgstr "Si è verificato un errore nell'aggiunta del contatto."
-#: ajax/addproperty.php:40
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr "il nome dell'elemento non è impostato."
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr "ID non impostato."
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr "Impossibile elaborare il contatto: "
+
+#: ajax/addproperty.php:56
msgid "Cannot add empty property."
msgstr "Impossibile aggiungere una proprietà vuota."
-#: ajax/addproperty.php:52
+#: ajax/addproperty.php:67
msgid "At least one of the address fields has to be filled out."
msgstr "Deve essere riempito almeno un indirizzo."
-#: ajax/addproperty.php:62
+#: ajax/addproperty.php:76
msgid "Trying to add duplicate property: "
msgstr "P"
-#: ajax/addproperty.php:120
-msgid "Error adding contact property."
-msgstr "Errore durante l'aggiunta della proprietà del contatto."
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
+msgstr "Errore durante l'aggiunta della proprietà del contatto: "
-#: ajax/categories/categoriesfor.php:15
+#: ajax/categories/categoriesfor.php:17
msgid "No ID provided"
msgstr "Nessun ID fornito"
-#: ajax/categories/categoriesfor.php:27
+#: ajax/categories/categoriesfor.php:34
msgid "Error setting checksum."
msgstr "Errore di impostazione del codice di controllo."
-#: ajax/categories/delete.php:29
+#: ajax/categories/delete.php:19
msgid "No categories selected for deletion."
msgstr "Nessuna categoria selezionata per l'eliminazione."
-#: ajax/categories/delete.php:36 ajax/categories/rescan.php:28
+#: ajax/categories/delete.php:26
msgid "No address books found."
msgstr "Nessuna rubrica trovata."
-#: ajax/categories/delete.php:44 ajax/categories/rescan.php:36
+#: ajax/categories/delete.php:34
msgid "No contacts found."
msgstr "Nessun contatto trovato."
-#: ajax/contactdetails.php:37
+#: ajax/contactdetails.php:31
msgid "Missing ID"
msgstr "ID mancante"
-#: ajax/contactdetails.php:41
+#: ajax/contactdetails.php:36
msgid "Error parsing VCard for ID: \""
msgstr "Errore in fase di elaborazione del file VCard per l'ID: \""
-#: ajax/createaddressbook.php:18
-msgid "Cannot add addressbook with an empty name."
-msgstr "Impossibile aggiungere una rubrica senza nome."
-
-#: ajax/createaddressbook.php:24
-msgid "Error adding addressbook."
-msgstr "Errore durante l'aggiunta della rubrica."
-
-#: ajax/createaddressbook.php:30
-msgid "Error activating addressbook."
-msgstr "Errore durante l'attivazione della rubrica."
-
-#: ajax/currentphoto.php:34 ajax/oc_photo.php:37 ajax/uploadphoto.php:41
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
#: ajax/uploadphoto.php:68
msgid "No contact ID was submitted."
msgstr "Nessun ID di contatto inviato."
-#: ajax/currentphoto.php:40
+#: ajax/currentphoto.php:36
msgid "Error reading contact photo."
msgstr "Errore di lettura della foto del contatto."
-#: ajax/currentphoto.php:52
+#: ajax/currentphoto.php:48
msgid "Error saving temporary file."
msgstr "Errore di salvataggio del file temporaneo."
-#: ajax/currentphoto.php:55
+#: ajax/currentphoto.php:51
msgid "The loading photo is not valid."
msgstr "La foto caricata non è valida."
-#: ajax/deletecard.php:37 ajax/saveproperty.php:58
-msgid "id is not set."
-msgstr "ID non impostato."
-
#: ajax/deleteproperty.php:36
msgid "Information about vCard is incorrect. Please reload the page."
msgstr "Informazioni sulla vCard non corrette. Ricarica la pagina."
@@ -114,328 +110,387 @@ msgstr "Informazioni sulla vCard non corrette. Ricarica la pagina."
msgid "Error deleting contact property."
msgstr "Errore durante l'eliminazione della proprietà del contatto."
-#: ajax/editname.php:37
+#: ajax/editname.php:31
msgid "Contact ID is missing."
msgstr "Manca l'ID del contatto."
-#: ajax/loadphoto.php:44
-msgid "Missing contact id."
-msgstr "ID di contatto mancante."
-
-#: ajax/oc_photo.php:41
+#: ajax/oc_photo.php:32
msgid "No photo path was submitted."
msgstr "Non è stato inviato alcun percorso a una foto."
-#: ajax/oc_photo.php:48
+#: ajax/oc_photo.php:39
msgid "File doesn't exist:"
msgstr "Il file non esiste:"
-#: ajax/oc_photo.php:54 ajax/oc_photo.php:57
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
msgid "Error loading image."
msgstr "Errore di caricamento immagine."
-#: ajax/savecrop.php:68
+#: ajax/savecrop.php:67
msgid "Error getting contact object."
-msgstr ""
+msgstr "Errore di recupero dell'oggetto contatto."
-#: ajax/savecrop.php:75
+#: ajax/savecrop.php:76
msgid "Error getting PHOTO property."
-msgstr ""
+msgstr "Errore di recupero della proprietà FOTO."
-#: ajax/savecrop.php:88
+#: ajax/savecrop.php:93
msgid "Error saving contact."
-msgstr ""
+msgstr "Errore di salvataggio del contatto."
-#: ajax/savecrop.php:98
+#: ajax/savecrop.php:103
msgid "Error resizing image"
-msgstr ""
+msgstr "Errore di ridimensionamento dell'immagine"
-#: ajax/savecrop.php:101
+#: ajax/savecrop.php:106
msgid "Error cropping image"
-msgstr ""
+msgstr "Errore di ritaglio dell'immagine"
-#: ajax/savecrop.php:104
+#: ajax/savecrop.php:109
msgid "Error creating temporary image"
-msgstr ""
+msgstr "Errore durante la creazione dell'immagine temporanea"
-#: ajax/savecrop.php:107
+#: ajax/savecrop.php:112
msgid "Error finding image: "
-msgstr ""
-
-#: ajax/saveproperty.php:55
-msgid "element name is not set."
-msgstr "il nome dell'elemento non è impostato."
+msgstr "Errore durante la ricerca dell'immagine: "
-#: ajax/saveproperty.php:61
+#: ajax/saveproperty.php:40
msgid "checksum is not set."
msgstr "il codice di controllo non è impostato."
-#: ajax/saveproperty.php:78
+#: ajax/saveproperty.php:59
msgid "Information about vCard is incorrect. Please reload the page: "
msgstr "Le informazioni della vCard non sono corrette. Ricarica la pagina: "
-#: ajax/saveproperty.php:83
+#: ajax/saveproperty.php:64
msgid "Something went FUBAR. "
msgstr "Qualcosa è andato storto. "
-#: ajax/saveproperty.php:150
+#: ajax/saveproperty.php:133
msgid "Error updating contact property."
msgstr "Errore durante l'aggiornamento della proprietà del contatto."
-#: ajax/updateaddressbook.php:20
+#: ajax/updateaddressbook.php:21
msgid "Cannot update addressbook with an empty name."
msgstr "Impossibile aggiornare una rubrica senza nome."
-#: ajax/updateaddressbook.php:26
+#: ajax/updateaddressbook.php:25
msgid "Error updating addressbook."
msgstr "Errore durante l'aggiornamento della rubrica."
-#: ajax/uploadimport.php:46 ajax/uploadimport.php:76
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
msgid "Error uploading contacts to storage."
msgstr "Errore di invio dei contatti in archivio."
-#: ajax/uploadimport.php:59 ajax/uploadphoto.php:77
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
msgid "There is no error, the file uploaded with success"
msgstr "Non ci sono errori, il file è stato inviato correttamente"
-#: ajax/uploadimport.php:60 ajax/uploadphoto.php:78
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
msgstr "Il file inviato supera la direttiva upload_max_filesize nel php.ini"
-#: ajax/uploadimport.php:61 ajax/uploadphoto.php:79
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
msgid ""
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
"the HTML form"
msgstr "Il file inviato supera la direttiva MAX_FILE_SIZE specificata nel modulo HTML"
-#: ajax/uploadimport.php:62 ajax/uploadphoto.php:80
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
msgid "The uploaded file was only partially uploaded"
msgstr "Il file è stato inviato solo parzialmente"
-#: ajax/uploadimport.php:63 ajax/uploadphoto.php:81
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
msgid "No file was uploaded"
msgstr "Nessun file è stato inviato"
-#: ajax/uploadimport.php:64 ajax/uploadphoto.php:82
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
msgid "Missing a temporary folder"
msgstr "Manca una cartella temporanea"
-#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:102
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
msgid "Couldn't save temporary image: "
-msgstr ""
+msgstr "Impossibile salvare l'immagine temporanea: "
-#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:105
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
msgid "Couldn't load temporary image: "
-msgstr ""
+msgstr "Impossibile caricare l'immagine temporanea: "
#: ajax/uploadphoto.php:71
msgid "No file was uploaded. Unknown error"
-msgstr ""
+msgstr "Nessun file è stato inviato. Errore sconosciuto"
-#: appinfo/app.php:17 templates/settings.php:3
+#: appinfo/app.php:19 templates/settings.php:3
msgid "Contacts"
msgstr "Contatti"
-#: js/contacts.js:24
+#: js/contacts.js:53
msgid "Sorry, this functionality has not been implemented yet"
-msgstr ""
+msgstr "Siamo spiacenti, questa funzionalità non è stata ancora implementata"
-#: js/contacts.js:24
+#: js/contacts.js:53
msgid "Not implemented"
-msgstr ""
+msgstr "Non implementata"
-#: js/contacts.js:29
+#: js/contacts.js:58
msgid "Couldn't get a valid address."
-msgstr ""
-
-#: js/contacts.js:29 js/contacts.js:334 js/contacts.js:341 js/contacts.js:355
-#: js/contacts.js:393 js/contacts.js:399 js/contacts.js:565 js/contacts.js:605
-#: js/contacts.js:631 js/contacts.js:668 js/contacts.js:747 js/contacts.js:753
-#: js/contacts.js:765 js/contacts.js:799 js/contacts.js:1056
-#: js/contacts.js:1064 js/contacts.js:1073 js/contacts.js:1130
-#: js/contacts.js:1146 js/contacts.js:1161 js/contacts.js:1173
-#: js/contacts.js:1196 js/contacts.js:1449 js/contacts.js:1457
-#: js/contacts.js:1483 js/contacts.js:1494 js/contacts.js:1509
-#: js/contacts.js:1526 js/contacts.js:1596 js/contacts.js:1644
-#: js/contacts.js:1654 js/contacts.js:1657
+msgstr "Impossibile ottenere un indirizzo valido."
+
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
msgid "Error"
-msgstr ""
+msgstr "Errore"
-#: js/contacts.js:364
-msgid "Are you sure you want to delete this contact?"
-msgstr ""
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr "Contatto"
-#: js/contacts.js:364
-msgid "Warning"
-msgstr ""
+#: js/contacts.js:389
+msgid "New"
+msgstr "Nuovo"
-#: js/contacts.js:605
+#: js/contacts.js:389
+msgid "New Contact"
+msgstr "Nuovo contatto"
+
+#: js/contacts.js:691
msgid "This property has to be non-empty."
-msgstr ""
+msgstr "Questa proprietà non può essere vuota."
-#: js/contacts.js:631
+#: js/contacts.js:717
msgid "Couldn't serialize elements."
-msgstr ""
+msgstr "Impossibile serializzare gli elementi."
-#: js/contacts.js:747 js/contacts.js:765
+#: js/contacts.js:826 js/contacts.js:844
msgid ""
"'deleteProperty' called without type argument. Please report at "
"bugs.owncloud.org"
-msgstr ""
+msgstr "'deleteProperty' invocata senza l'argomento di tipo. Segnalalo a bugs.owncloud.org"
-#: js/contacts.js:781
+#: js/contacts.js:860
msgid "Edit name"
-msgstr ""
+msgstr "Modifica il nome"
-#: js/contacts.js:1056
+#: js/contacts.js:1141
msgid "No files selected for upload."
-msgstr ""
+msgstr "Nessun file selezionato per l'invio"
-#: js/contacts.js:1064 js/contacts.js:1449 js/contacts.js:1634
+#: js/contacts.js:1149
msgid ""
"The file you are trying to upload exceed the maximum size for file uploads "
"on this server."
-msgstr ""
-
-#: js/contacts.js:1119
-msgid "Select photo"
-msgstr ""
+msgstr "Il file che stai cercando di inviare supera la dimensione massima per l'invio dei file su questo server."
-#: js/contacts.js:1257 js/contacts.js:1290
+#: js/contacts.js:1314 js/contacts.js:1348
msgid "Select type"
-msgstr ""
-
-#: js/contacts.js:1305 templates/part.importaddressbook.php:25
-msgid "Drop a VCF file to import contacts."
-msgstr "Rilascia un file VCF per importare i contatti."
-
-#: js/contacts.js:1475
-msgid "Import done. Success/Failure: "
-msgstr ""
-
-#: js/contacts.js:1476
-msgid "OK"
-msgstr ""
-
-#: js/contacts.js:1494
-msgid "Displayname cannot be empty."
-msgstr ""
-
-#: js/contacts.js:1634
-msgid "Upload too large"
-msgstr ""
-
-#: js/contacts.js:1638
-msgid "Only image files can be used as profile picture."
-msgstr ""
-
-#: js/contacts.js:1638
-msgid "Wrong file type"
-msgstr ""
-
-#: js/contacts.js:1644
-msgid ""
-"Your browser doesn't support AJAX upload. Please click on the profile "
-"picture to select a photo to upload."
-msgstr ""
+msgstr "Seleziona il tipo"
#: js/loader.js:49
msgid "Result: "
-msgstr ""
+msgstr "Risultato: "
#: js/loader.js:49
msgid " imported, "
-msgstr ""
+msgstr " importato, "
#: js/loader.js:49
msgid " failed."
-msgstr ""
+msgstr " non riuscito."
-#: lib/app.php:30
+#: lib/app.php:29
msgid "Addressbook not found."
msgstr "Rubrica non trovata."
-#: lib/app.php:34
+#: lib/app.php:33
msgid "This is not your addressbook."
msgstr "Questa non è la tua rubrica."
-#: lib/app.php:45
+#: lib/app.php:44
msgid "Contact could not be found."
msgstr "Il contatto non può essere trovato."
-#: lib/app.php:101 templates/part.contact.php:109
+#: lib/app.php:100 templates/part.contact.php:116
msgid "Address"
msgstr "Indirizzo"
-#: lib/app.php:102
+#: lib/app.php:101
msgid "Telephone"
msgstr "Telefono"
-#: lib/app.php:103 templates/part.contact.php:108
+#: lib/app.php:102 templates/part.contact.php:115
msgid "Email"
msgstr "Email"
-#: lib/app.php:104 templates/part.contact.php:33 templates/part.contact.php:34
-#: templates/part.contact.php:104
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
msgid "Organization"
msgstr "Organizzazione"
-#: lib/app.php:116 lib/app.php:123 lib/app.php:133
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
msgid "Work"
msgstr "Lavoro"
-#: lib/app.php:117 lib/app.php:121 lib/app.php:134
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
msgid "Home"
msgstr "Casa"
-#: lib/app.php:122
+#: lib/app.php:121
msgid "Mobile"
msgstr "Cellulare"
-#: lib/app.php:124
+#: lib/app.php:123
msgid "Text"
msgstr "Testo"
-#: lib/app.php:125
+#: lib/app.php:124
msgid "Voice"
msgstr "Voce"
-#: lib/app.php:126
+#: lib/app.php:125
msgid "Message"
msgstr "Messaggio"
-#: lib/app.php:127
+#: lib/app.php:126
msgid "Fax"
msgstr "Fax"
-#: lib/app.php:128
+#: lib/app.php:127
msgid "Video"
msgstr "Video"
-#: lib/app.php:129
+#: lib/app.php:128
msgid "Pager"
msgstr "Cercapersone"
-#: lib/app.php:135
+#: lib/app.php:134
msgid "Internet"
msgstr "Internet"
-#: lib/hooks.php:79
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
+msgstr "Compleanno"
+
+#: lib/app.php:170
+msgid "Business"
+msgstr "Lavoro"
+
+#: lib/app.php:171
+msgid "Call"
+msgstr "Chiama"
+
+#: lib/app.php:172
+msgid "Clients"
+msgstr "Client"
+
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr "Corriere"
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr "Festività"
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr "Idee"
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr "Viaggio"
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr "Anniversario"
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr "Riunione"
+
+#: lib/app.php:179
+msgid "Other"
+msgstr "Altro"
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr "Personale"
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr "Progetti"
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr "Domande"
+
+#: lib/hooks.php:102
msgid "{name}'s Birthday"
msgstr "Data di nascita di {name}"
-#: lib/search.php:22
-msgid "Contact"
-msgstr "Contatto"
-
-#: templates/index.php:13
+#: templates/index.php:15
msgid "Add Contact"
msgstr "Aggiungi contatto"
-#: templates/index.php:14
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr "Importa"
+
+#: templates/index.php:20
msgid "Addressbooks"
msgstr "Rubriche"
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr "Chiudi"
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr "Scorciatoie da tastiera"
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr "Navigazione"
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr "Contatto successivo in elenco"
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr "Contatto precedente in elenco"
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr "Espandi/Contrai la rubrica corrente"
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr "Rubrica successiva/precedente"
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr "Azioni"
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr "Aggiorna l'elenco dei contatti"
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr "Aggiungi un nuovo contatto"
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr "Aggiungi una nuova rubrica"
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr "Elimina il contatto corrente"
+
#: templates/part.chooseaddressbook.php:1
msgid "Configure Address Books"
msgstr "Configura rubrica"
@@ -444,11 +499,7 @@ msgstr "Configura rubrica"
msgid "New Address Book"
msgstr "Nuova rubrica"
-#: templates/part.chooseaddressbook.php:17
-msgid "Import from VCF"
-msgstr "Importa da VCF"
-
-#: templates/part.chooseaddressbook.php:22
+#: templates/part.chooseaddressbook.php:21
#: templates/part.chooseaddressbook.rowfields.php:8
msgid "CardDav Link"
msgstr "Link CardDav"
@@ -462,186 +513,195 @@ msgid "Edit"
msgstr "Modifica"
#: templates/part.chooseaddressbook.rowfields.php:17
-#: templates/part.contact.php:34 templates/part.contact.php:36
-#: templates/part.contact.php:38 templates/part.contact.php:42
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
msgid "Delete"
msgstr "Elimina"
-#: templates/part.contact.php:12
-msgid "Download contact"
-msgstr "Scarica contatto"
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
+msgstr "Rilascia una foto da inviare"
-#: templates/part.contact.php:13
-msgid "Delete contact"
-msgstr "Elimina contatto"
+#: templates/part.contact.php:18
+msgid "Delete current photo"
+msgstr "Elimina la foto corrente"
#: templates/part.contact.php:19
-msgid "Drop photo to upload"
-msgstr "Rilascia una foto da inviare"
+msgid "Edit current photo"
+msgstr "Modifica la foto corrente"
+
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr "Invia una nuova foto"
-#: templates/part.contact.php:29
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr "Seleziona la foto da ownCloud"
+
+#: templates/part.contact.php:34
msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
msgstr "Formato personalizzato, nome breve, nome completo, invertito o invertito con virgola"
-#: templates/part.contact.php:30
+#: templates/part.contact.php:35
msgid "Edit name details"
msgstr "Modifica dettagli del nome"
-#: templates/part.contact.php:35 templates/part.contact.php:105
+#: templates/part.contact.php:40 templates/part.contact.php:112
msgid "Nickname"
msgstr "Pseudonimo"
-#: templates/part.contact.php:36
+#: templates/part.contact.php:41
msgid "Enter nickname"
msgstr "Inserisci pseudonimo"
-#: templates/part.contact.php:37 templates/part.contact.php:106
-msgid "Birthday"
-msgstr "Compleanno"
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
+msgstr "Sito web"
+
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr "http://www.somesite.com"
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr "Vai al sito web"
-#: templates/part.contact.php:38
+#: templates/part.contact.php:45
msgid "dd-mm-yyyy"
msgstr "gg-mm-aaaa"
-#: templates/part.contact.php:39 templates/part.contact.php:111
+#: templates/part.contact.php:46 templates/part.contact.php:119
msgid "Groups"
msgstr "Gruppi"
-#: templates/part.contact.php:41
+#: templates/part.contact.php:48
msgid "Separate groups with commas"
msgstr "Separa i gruppi con virgole"
-#: templates/part.contact.php:42
+#: templates/part.contact.php:49
msgid "Edit groups"
msgstr "Modifica gruppi"
-#: templates/part.contact.php:55 templates/part.contact.php:69
+#: templates/part.contact.php:62 templates/part.contact.php:76
msgid "Preferred"
msgstr "Preferito"
-#: templates/part.contact.php:56
+#: templates/part.contact.php:63
msgid "Please specify a valid email address."
msgstr "Specifica un indirizzo email valido"
-#: templates/part.contact.php:56
+#: templates/part.contact.php:63
msgid "Enter email address"
msgstr "Inserisci indirizzo email"
-#: templates/part.contact.php:60
+#: templates/part.contact.php:67
msgid "Mail to address"
msgstr "Invia per email"
-#: templates/part.contact.php:61
+#: templates/part.contact.php:68
msgid "Delete email address"
msgstr "Elimina l'indirizzo email"
-#: templates/part.contact.php:70
+#: templates/part.contact.php:77
msgid "Enter phone number"
msgstr "Inserisci il numero di telefono"
-#: templates/part.contact.php:74
+#: templates/part.contact.php:81
msgid "Delete phone number"
msgstr "Elimina il numero di telefono"
-#: templates/part.contact.php:84
+#: templates/part.contact.php:91
msgid "View on map"
msgstr "Visualizza sulla mappa"
-#: templates/part.contact.php:84
+#: templates/part.contact.php:91
msgid "Edit address details"
msgstr "Modifica dettagli dell'indirizzo"
-#: templates/part.contact.php:95
+#: templates/part.contact.php:102
msgid "Add notes here."
msgstr "Aggiungi qui le note."
-#: templates/part.contact.php:101
+#: templates/part.contact.php:109
msgid "Add field"
msgstr "Aggiungi campo"
-#: templates/part.contact.php:103
-msgid "Profile picture"
-msgstr "Immagine del profilo"
-
-#: templates/part.contact.php:107
+#: templates/part.contact.php:114
msgid "Phone"
msgstr "Telefono"
-#: templates/part.contact.php:110
+#: templates/part.contact.php:117
msgid "Note"
msgstr "Nota"
-#: templates/part.contactphoto.php:8
-msgid "Delete current photo"
-msgstr "Elimina la foto corrente"
-
-#: templates/part.contactphoto.php:9
-msgid "Edit current photo"
-msgstr "Modifica la foto corrente"
-
-#: templates/part.contactphoto.php:10
-msgid "Upload new photo"
-msgstr "Invia una nuova foto"
+#: templates/part.contact.php:122
+msgid "Download contact"
+msgstr "Scarica contatto"
-#: templates/part.contactphoto.php:11
-msgid "Select photo from ownCloud"
-msgstr "Seleziona la foto da ownCloud"
+#: templates/part.contact.php:123
+msgid "Delete contact"
+msgstr "Elimina contatto"
-#: templates/part.cropphoto.php:64
+#: templates/part.cropphoto.php:65
msgid "The temporary image has been removed from cache."
-msgstr ""
+msgstr "L'immagine temporanea è stata rimossa dalla cache."
-#: templates/part.edit_address_dialog.php:9
+#: templates/part.edit_address_dialog.php:6
msgid "Edit address"
msgstr "Modifica indirizzo"
-#: templates/part.edit_address_dialog.php:14
+#: templates/part.edit_address_dialog.php:10
msgid "Type"
msgstr "Tipo"
-#: templates/part.edit_address_dialog.php:22
-#: templates/part.edit_address_dialog.php:25
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
msgid "PO Box"
msgstr "Casella postale"
-#: templates/part.edit_address_dialog.php:29
-#: templates/part.edit_address_dialog.php:32
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr "Indirizzo"
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr "Via e numero"
+
+#: templates/part.edit_address_dialog.php:30
msgid "Extended"
msgstr "Esteso"
-#: templates/part.edit_address_dialog.php:35
-#: templates/part.edit_address_dialog.php:38
-msgid "Street"
-msgstr "Via"
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
+msgstr "Numero appartamento ecc."
-#: templates/part.edit_address_dialog.php:41
-#: templates/part.edit_address_dialog.php:44
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
msgid "City"
msgstr "Città"
-#: templates/part.edit_address_dialog.php:47
-#: templates/part.edit_address_dialog.php:50
+#: templates/part.edit_address_dialog.php:42
msgid "Region"
msgstr "Regione"
-#: templates/part.edit_address_dialog.php:53
-#: templates/part.edit_address_dialog.php:56
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
+msgstr "Ad es. stato o provincia"
+
+#: templates/part.edit_address_dialog.php:48
msgid "Zipcode"
msgstr "CAP"
-#: templates/part.edit_address_dialog.php:59
-#: templates/part.edit_address_dialog.php:62
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
+msgstr "CAP"
+
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
msgid "Country"
msgstr "Stato"
-#: templates/part.edit_categories_dialog.php:4
-msgid "Edit categories"
-msgstr "Modifica categorie"
-
-#: templates/part.edit_categories_dialog.php:14
-msgid "Add"
-msgstr "Aggiungi"
-
#: templates/part.edit_name_dialog.php:16
msgid "Addressbook"
msgstr "Rubrica"
@@ -747,7 +807,6 @@ msgid "Submit"
msgstr "Invia"
#: templates/part.editaddressbook.php:30
-#: templates/part.importaddressbook.php:34
msgid "Cancel"
msgstr "Annulla"
@@ -767,33 +826,10 @@ msgstr "crea una nuova rubrica"
msgid "Name of new addressbook"
msgstr "Nome della nuova rubrica"
-#: templates/part.import.php:17
-msgid "Import"
-msgstr "Importa"
-
#: templates/part.import.php:20
msgid "Importing contacts"
msgstr "Importazione contatti"
-#: templates/part.import.php:24
-msgid "Close"
-msgstr ""
-
-#: templates/part.importaddressbook.php:12
-msgid ""
-"Currently this import function doesn't work while encryption is enabled.<br "
-"/>Please upload your VCF file with the file manager and click on it to "
-"import."
-msgstr ""
-
-#: templates/part.importaddressbook.php:16
-msgid "Select address book to import to:"
-msgstr "Seleziona la rubrica di destinazione:"
-
-#: templates/part.importaddressbook.php:26
-msgid "Select from HD"
-msgstr "Seleziona da disco"
-
#: templates/part.no_contacts.php:2
msgid "You have no contacts in your addressbook."
msgstr "Non hai contatti nella rubrica."
@@ -806,6 +842,18 @@ msgstr "Aggiungi contatto"
msgid "Configure addressbooks"
msgstr "Configura rubriche"
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr "Seleziona rubriche"
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr "Inserisci il nome"
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr "Inserisci una descrizione"
+
#: templates/settings.php:4
msgid "CardDAV syncing addresses"
msgstr "Indirizzi di sincronizzazione CardDAV"
@@ -821,3 +869,7 @@ msgstr "Indirizzo principale (Kontact e altri)"
#: templates/settings.php:8
msgid "iOS/OS X"
msgstr "iOS/OS X"
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr "Collegamento(i) cartella vCard sola lettura"
diff --git a/l10n/it/files.po b/l10n/it/files.po
index 8db41dc6477..196985d5f8d 100644
--- a/l10n/it/files.po
+++ b/l10n/it/files.po
@@ -11,43 +11,43 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Italian (http://www.transifex.net/projects/p/owncloud/language/it/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 20:35+0000\n"
+"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: ajax/upload.php:19
+#: ajax/upload.php:20
msgid "There is no error, the file uploaded with success"
msgstr "Non ci sono errori, file caricato con successo"
-#: ajax/upload.php:20
+#: ajax/upload.php:21
msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
msgstr "Il file caricato supera il valore upload_max_filesize in php.ini"
-#: ajax/upload.php:21
+#: ajax/upload.php:22
msgid ""
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
"the HTML form"
msgstr "Il file caricato supera il valore MAX_FILE_SIZE definito nel form HTML"
-#: ajax/upload.php:22
+#: ajax/upload.php:23
msgid "The uploaded file was only partially uploaded"
msgstr "Il file è stato parzialmente caricato"
-#: ajax/upload.php:23
+#: ajax/upload.php:24
msgid "No file was uploaded"
msgstr "Nessun file è stato caricato"
-#: ajax/upload.php:24
+#: ajax/upload.php:25
msgid "Missing a temporary folder"
msgstr "Cartella temporanea mancante"
-#: ajax/upload.php:25
+#: ajax/upload.php:26
msgid "Failed to write to disk"
msgstr "Scrittura su disco non riuscita"
@@ -55,57 +55,65 @@ msgstr "Scrittura su disco non riuscita"
msgid "Files"
msgstr "File"
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr "Rimuovi condivisione"
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr "Elimina"
+
#: js/filelist.js:186
msgid "undo deletion"
-msgstr ""
+msgstr "annulla l'eliminazione"
#: js/files.js:170
msgid "generating ZIP-file, it may take some time."
-msgstr ""
+msgstr "creazione file ZIP, potrebbe richiedere del tempo."
#: js/files.js:199
msgid "Unable to upload your file as it is a directory or has 0 bytes"
-msgstr ""
+msgstr "Impossibile inviare il file poiché è una cartella o ha dimensione 0 byte"
#: js/files.js:199
msgid "Upload Error"
-msgstr ""
+msgstr "Errore di invio"
#: js/files.js:227 js/files.js:318 js/files.js:347
msgid "Pending"
-msgstr ""
+msgstr "In corso"
#: js/files.js:332
msgid "Upload cancelled."
-msgstr ""
+msgstr "Invio annullato"
#: js/files.js:456
msgid "Invalid name, '/' is not allowed."
-msgstr ""
+msgstr "Nome non valido"
-#: js/files.js:626 templates/index.php:55
+#: js/files.js:631 templates/index.php:55
msgid "Size"
msgstr "Dimensione"
-#: js/files.js:627 templates/index.php:56
+#: js/files.js:632 templates/index.php:56
msgid "Modified"
msgstr "Modificato"
-#: js/files.js:654
+#: js/files.js:659
msgid "folder"
-msgstr ""
+msgstr "cartella"
-#: js/files.js:656
+#: js/files.js:661
msgid "folders"
-msgstr ""
+msgstr "cartelle"
-#: js/files.js:664
+#: js/files.js:669
msgid "file"
-msgstr ""
+msgstr "file"
-#: js/files.js:666
+#: js/files.js:671
msgid "files"
-msgstr ""
+msgstr "file"
#: templates/admin.php:5
msgid "File handling"
@@ -175,10 +183,6 @@ msgstr "Condividi"
msgid "Download"
msgstr "Scarica"
-#: templates/index.php:56
-msgid "Delete"
-msgstr "Elimina"
-
#: templates/index.php:64
msgid "Upload too large"
msgstr "Il file caricato è troppo grande"
diff --git a/l10n/it/gallery.po b/l10n/it/gallery.po
index 794458ec1f1..d60292cea15 100644
--- a/l10n/it/gallery.po
+++ b/l10n/it/gallery.po
@@ -10,71 +10,35 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Italian (http://www.transifex.net/projects/p/owncloud/language/it/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 20:36+0000\n"
+"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Language: it\n"
"Plural-Forms: nplurals=2; plural=(n != 1)\n"
-#: appinfo/app.php:37
+#: appinfo/app.php:39
msgid "Pictures"
msgstr "Immagini"
-#: js/album_cover.js:44
+#: js/pictures.js:12
msgid "Share gallery"
-msgstr ""
+msgstr "Condividi la galleria"
-#: js/album_cover.js:64 js/album_cover.js:100 js/album_cover.js:133
+#: js/pictures.js:32
msgid "Error: "
-msgstr ""
+msgstr "Errore: "
-#: js/album_cover.js:64 js/album_cover.js:100
+#: js/pictures.js:32
msgid "Internal error"
-msgstr ""
-
-#: js/album_cover.js:114
-msgid "Scanning root"
-msgstr ""
-
-#: js/album_cover.js:115
-msgid "Default order"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Ascending"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Descending"
-msgstr ""
-
-#: js/album_cover.js:117 templates/index.php:19
-msgid "Settings"
-msgstr "Impostazioni"
-
-#: js/album_cover.js:122
-msgid "Scanning root cannot be empty"
-msgstr ""
-
-#: js/album_cover.js:122 js/album_cover.js:133
-msgid "Error"
-msgstr ""
-
-#: templates/index.php:16
-msgid "Rescan"
-msgstr "Nuova scansione"
-
-#: templates/index.php:17
-msgid "Stop"
-msgstr "Ferma"
+msgstr "Errore interno"
-#: templates/index.php:18
-msgid "Share"
-msgstr "Condividi"
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr "Presentazione"
#: templates/view_album.php:19
msgid "Back"
diff --git a/l10n/it/settings.po b/l10n/it/settings.po
index 56936ed81f1..6ae91a7c786 100644
--- a/l10n/it/settings.po
+++ b/l10n/it/settings.po
@@ -14,10 +14,10 @@ msgid ""
msgstr ""
"Project-Id-Version: ownCloud\n"
"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
-"PO-Revision-Date: 2012-06-05 22:15+0000\n"
-"Last-Translator: icewind <icewind1991@gmail.com>\n"
-"Language-Team: Italian (http://www.transifex.net/projects/p/owncloud/language/it/)\n"
+"POT-Creation-Date: 2012-07-26 02:01+0200\n"
+"PO-Revision-Date: 2012-07-25 20:36+0000\n"
+"Last-Translator: Vincenzo Reale <vinx.reale@gmail.com>\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/owncloud/language/it/)\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
@@ -26,65 +26,69 @@ msgstr ""
#: ajax/lostpassword.php:14
msgid "Email saved"
-msgstr ""
+msgstr "Email salvata"
#: ajax/lostpassword.php:16
msgid "Invalid email"
-msgstr ""
+msgstr "Email non valida"
-#: ajax/openid.php:15
+#: ajax/openid.php:16
msgid "OpenID Changed"
msgstr "OpenID modificato"
-#: ajax/openid.php:17 ajax/setlanguage.php:19 ajax/setlanguage.php:22
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
msgid "Invalid request"
msgstr "Richiesta non valida"
-#: ajax/setlanguage.php:17
+#: ajax/setlanguage.php:18
msgid "Language changed"
msgstr "Lingua modificata"
#: js/apps.js:31 js/apps.js:67
msgid "Disable"
-msgstr ""
+msgstr "Disabilita"
#: js/apps.js:31 js/apps.js:54
msgid "Enable"
-msgstr ""
+msgstr "Abilita"
#: js/personal.js:69
msgid "Saving..."
-msgstr ""
+msgstr "Salvataggio in corso..."
-#: personal.php:40 personal.php:41
+#: personal.php:41 personal.php:42
msgid "__language_name__"
msgstr "Italiano"
-#: templates/admin.php:13
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr "Avviso di sicurezza"
+
+#: templates/admin.php:28
msgid "Log"
msgstr "Registro"
-#: templates/admin.php:40
+#: templates/admin.php:55
msgid "More"
msgstr "Altro"
-#: templates/apps.php:8
+#: templates/apps.php:10
msgid "Add your App"
msgstr "Aggiungi la tua applicazione"
-#: templates/apps.php:22
+#: templates/apps.php:24
msgid "Select an App"
msgstr "Seleziona un'applicazione"
-#: templates/apps.php:25
+#: templates/apps.php:27
msgid "See application page at apps.owncloud.com"
-msgstr ""
+msgstr "Vedere la pagina dell'applicazione su apps.owncloud.com"
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "-licensed"
msgstr "-rilasciato"
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "by"
msgstr "da"
@@ -176,34 +180,34 @@ msgstr "Migliora la traduzione"
msgid "use this address to connect to your ownCloud in your file manager"
msgstr "usa questo indirizzo per connetterti al tuo ownCloud dal gestore file"
-#: templates/users.php:15 templates/users.php:44
+#: templates/users.php:15 templates/users.php:60
msgid "Name"
msgstr "Nome"
-#: templates/users.php:16 templates/users.php:45
+#: templates/users.php:17 templates/users.php:61
msgid "Password"
msgstr "Password"
-#: templates/users.php:17 templates/users.php:46 templates/users.php:60
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
msgid "Groups"
msgstr "Gruppi"
-#: templates/users.php:22
+#: templates/users.php:25
msgid "Create"
msgstr "Crea"
-#: templates/users.php:25
+#: templates/users.php:28
msgid "Default Quota"
msgstr "Quota predefinita"
-#: templates/users.php:35 templates/users.php:74
+#: templates/users.php:47 templates/users.php:103
msgid "Other"
msgstr "Altro"
-#: templates/users.php:47
+#: templates/users.php:63
msgid "Quota"
msgstr "Quote"
-#: templates/users.php:80
+#: templates/users.php:110
msgid "Delete"
msgstr "Elimina"
diff --git a/l10n/so/calendar.po b/l10n/so/calendar.po
new file mode 100644
index 00000000000..139a523a52c
--- /dev/null
+++ b/l10n/so/calendar.po
@@ -0,0 +1,814 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
+msgid "No calendars found."
+msgstr ""
+
+#: ajax/categories/rescan.php:37
+msgid "No events found."
+msgstr ""
+
+#: ajax/event/edit.form.php:20
+msgid "Wrong calendar"
+msgstr ""
+
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr ""
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
+#: ajax/settings/guesstimezone.php:25
+msgid "New Timezone:"
+msgstr ""
+
+#: ajax/settings/settimezone.php:23
+msgid "Timezone changed"
+msgstr ""
+
+#: ajax/settings/settimezone.php:25
+msgid "Invalid request"
+msgstr ""
+
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
+#: templates/settings.php:12
+msgid "Calendar"
+msgstr ""
+
+#: js/calendar.js:828
+msgid "ddd"
+msgstr ""
+
+#: js/calendar.js:829
+msgid "ddd M/d"
+msgstr ""
+
+#: js/calendar.js:830
+msgid "dddd M/d"
+msgstr ""
+
+#: js/calendar.js:833
+msgid "MMMM yyyy"
+msgstr ""
+
+#: js/calendar.js:835
+msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
+msgstr ""
+
+#: js/calendar.js:837
+msgid "dddd, MMM d, yyyy"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:122
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:129
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:130
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:131
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:132
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:133
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Questions"
+msgstr ""
+
+#: lib/app.php:135
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr ""
+
+#: lib/app.php:359 lib/app.php:399
+msgid "unnamed"
+msgstr ""
+
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr ""
+
+#: lib/object.php:372
+msgid "Does not repeat"
+msgstr ""
+
+#: lib/object.php:373
+msgid "Daily"
+msgstr ""
+
+#: lib/object.php:374
+msgid "Weekly"
+msgstr ""
+
+#: lib/object.php:375
+msgid "Every Weekday"
+msgstr ""
+
+#: lib/object.php:376
+msgid "Bi-Weekly"
+msgstr ""
+
+#: lib/object.php:377
+msgid "Monthly"
+msgstr ""
+
+#: lib/object.php:378
+msgid "Yearly"
+msgstr ""
+
+#: lib/object.php:388
+msgid "never"
+msgstr ""
+
+#: lib/object.php:389
+msgid "by occurrences"
+msgstr ""
+
+#: lib/object.php:390
+msgid "by date"
+msgstr ""
+
+#: lib/object.php:400
+msgid "by monthday"
+msgstr ""
+
+#: lib/object.php:401
+msgid "by weekday"
+msgstr ""
+
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
+msgid "Monday"
+msgstr ""
+
+#: lib/object.php:412 templates/calendar.php:5
+msgid "Tuesday"
+msgstr ""
+
+#: lib/object.php:413 templates/calendar.php:5
+msgid "Wednesday"
+msgstr ""
+
+#: lib/object.php:414 templates/calendar.php:5
+msgid "Thursday"
+msgstr ""
+
+#: lib/object.php:415 templates/calendar.php:5
+msgid "Friday"
+msgstr ""
+
+#: lib/object.php:416 templates/calendar.php:5
+msgid "Saturday"
+msgstr ""
+
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
+msgid "Sunday"
+msgstr ""
+
+#: lib/object.php:427
+msgid "events week of month"
+msgstr ""
+
+#: lib/object.php:428
+msgid "first"
+msgstr ""
+
+#: lib/object.php:429
+msgid "second"
+msgstr ""
+
+#: lib/object.php:430
+msgid "third"
+msgstr ""
+
+#: lib/object.php:431
+msgid "fourth"
+msgstr ""
+
+#: lib/object.php:432
+msgid "fifth"
+msgstr ""
+
+#: lib/object.php:433
+msgid "last"
+msgstr ""
+
+#: lib/object.php:467 templates/calendar.php:7
+msgid "January"
+msgstr ""
+
+#: lib/object.php:468 templates/calendar.php:7
+msgid "February"
+msgstr ""
+
+#: lib/object.php:469 templates/calendar.php:7
+msgid "March"
+msgstr ""
+
+#: lib/object.php:470 templates/calendar.php:7
+msgid "April"
+msgstr ""
+
+#: lib/object.php:471 templates/calendar.php:7
+msgid "May"
+msgstr ""
+
+#: lib/object.php:472 templates/calendar.php:7
+msgid "June"
+msgstr ""
+
+#: lib/object.php:473 templates/calendar.php:7
+msgid "July"
+msgstr ""
+
+#: lib/object.php:474 templates/calendar.php:7
+msgid "August"
+msgstr ""
+
+#: lib/object.php:475 templates/calendar.php:7
+msgid "September"
+msgstr ""
+
+#: lib/object.php:476 templates/calendar.php:7
+msgid "October"
+msgstr ""
+
+#: lib/object.php:477 templates/calendar.php:7
+msgid "November"
+msgstr ""
+
+#: lib/object.php:478 templates/calendar.php:7
+msgid "December"
+msgstr ""
+
+#: lib/object.php:488
+msgid "by events date"
+msgstr ""
+
+#: lib/object.php:489
+msgid "by yearday(s)"
+msgstr ""
+
+#: lib/object.php:490
+msgid "by weeknumber(s)"
+msgstr ""
+
+#: lib/object.php:491
+msgid "by day and month"
+msgstr ""
+
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
+msgid "Date"
+msgstr ""
+
+#: lib/search.php:43
+msgid "Cal."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr ""
+
+#: templates/calendar.php:11
+msgid "All day"
+msgstr ""
+
+#: templates/calendar.php:13
+msgid "Missing fields"
+msgstr ""
+
+#: templates/calendar.php:14 templates/part.eventform.php:19
+#: templates/part.showevent.php:11
+msgid "Title"
+msgstr ""
+
+#: templates/calendar.php:16
+msgid "From Date"
+msgstr ""
+
+#: templates/calendar.php:17
+msgid "From Time"
+msgstr ""
+
+#: templates/calendar.php:18
+msgid "To Date"
+msgstr ""
+
+#: templates/calendar.php:19
+msgid "To Time"
+msgstr ""
+
+#: templates/calendar.php:20
+msgid "The event ends before it starts"
+msgstr ""
+
+#: templates/calendar.php:21
+msgid "There was a database fail"
+msgstr ""
+
+#: templates/calendar.php:38
+msgid "Week"
+msgstr ""
+
+#: templates/calendar.php:39
+msgid "Month"
+msgstr ""
+
+#: templates/calendar.php:40
+msgid "List"
+msgstr ""
+
+#: templates/calendar.php:44
+msgid "Today"
+msgstr ""
+
+#: templates/calendar.php:45
+msgid "Calendars"
+msgstr ""
+
+#: templates/calendar.php:59
+msgid "There was a fail, while parsing the file."
+msgstr ""
+
+#: templates/part.choosecalendar.php:1
+msgid "Choose active calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:2
+msgid "Your calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:27
+#: templates/part.choosecalendar.rowfields.php:11
+msgid "CalDav Link"
+msgstr ""
+
+#: templates/part.choosecalendar.php:31
+msgid "Shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.php:48
+msgid "No shared calendars"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:8
+msgid "Share Calendar"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:14
+msgid "Download"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:17
+msgid "Edit"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.php:20
+#: templates/part.editevent.php:9
+msgid "Delete"
+msgstr ""
+
+#: templates/part.choosecalendar.rowfields.shared.php:4
+msgid "shared with you by"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "New calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:9
+msgid "Edit calendar"
+msgstr ""
+
+#: templates/part.editcalendar.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editcalendar.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editcalendar.php:29
+msgid "Calendar color"
+msgstr ""
+
+#: templates/part.editcalendar.php:42
+msgid "Save"
+msgstr ""
+
+#: templates/part.editcalendar.php:42 templates/part.editevent.php:8
+#: templates/part.newevent.php:6
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editcalendar.php:43
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.editevent.php:1
+msgid "Edit an event"
+msgstr ""
+
+#: templates/part.editevent.php:10
+msgid "Export"
+msgstr ""
+
+#: templates/part.eventform.php:8 templates/part.showevent.php:3
+msgid "Eventinfo"
+msgstr ""
+
+#: templates/part.eventform.php:9 templates/part.showevent.php:4
+msgid "Repeating"
+msgstr ""
+
+#: templates/part.eventform.php:10 templates/part.showevent.php:5
+msgid "Alarm"
+msgstr ""
+
+#: templates/part.eventform.php:11 templates/part.showevent.php:6
+msgid "Attendees"
+msgstr ""
+
+#: templates/part.eventform.php:13
+msgid "Share"
+msgstr ""
+
+#: templates/part.eventform.php:21
+msgid "Title of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:27 templates/part.showevent.php:19
+msgid "Category"
+msgstr ""
+
+#: templates/part.eventform.php:29
+msgid "Separate categories with commas"
+msgstr ""
+
+#: templates/part.eventform.php:30
+msgid "Edit categories"
+msgstr ""
+
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
+msgid "All Day Event"
+msgstr ""
+
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
+msgid "From"
+msgstr ""
+
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
+msgid "To"
+msgstr ""
+
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
+msgid "Advanced options"
+msgstr ""
+
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
+msgid "Location"
+msgstr ""
+
+#: templates/part.eventform.php:83
+msgid "Location of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
+msgid "Description"
+msgstr ""
+
+#: templates/part.eventform.php:91
+msgid "Description of the Event"
+msgstr ""
+
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
+msgid "Repeat"
+msgstr ""
+
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
+msgid "Advanced"
+msgstr ""
+
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
+msgid "Select weekdays"
+msgstr ""
+
+#: templates/part.eventform.php:164 templates/part.eventform.php:177
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
+msgid "Select days"
+msgstr ""
+
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
+msgid "and the events day of year."
+msgstr ""
+
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
+msgid "and the events day of month."
+msgstr ""
+
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
+msgid "Select months"
+msgstr ""
+
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
+msgid "Select weeks"
+msgstr ""
+
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
+msgid "and the events week of year."
+msgstr ""
+
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
+msgid "Interval"
+msgstr ""
+
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
+msgid "End"
+msgstr ""
+
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
+msgid "occurrences"
+msgstr ""
+
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr ""
+
+#: templates/part.import.php:17
+msgid "Import a calendar file"
+msgstr ""
+
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr ""
+
+#: templates/part.import.php:36
+msgid "Name of new calendar"
+msgstr ""
+
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr ""
+
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr ""
+
+#: templates/part.import.php:47
+msgid "Import"
+msgstr ""
+
+#: templates/part.import.php:56
+msgid "Close Dialog"
+msgstr ""
+
+#: templates/part.newevent.php:1
+msgid "Create a new event"
+msgstr ""
+
+#: templates/part.showevent.php:1
+msgid "View an event"
+msgstr ""
+
+#: templates/part.showevent.php:23
+msgid "No categories selected"
+msgstr ""
+
+#: templates/part.showevent.php:37
+msgid "of"
+msgstr ""
+
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
+msgid "at"
+msgstr ""
+
+#: templates/settings.php:14
+msgid "Timezone"
+msgstr ""
+
+#: templates/settings.php:31
+msgid "Check always for changes of the timezone"
+msgstr ""
+
+#: templates/settings.php:33
+msgid "Timeformat"
+msgstr ""
+
+#: templates/settings.php:35
+msgid "24h"
+msgstr ""
+
+#: templates/settings.php:36
+msgid "12h"
+msgstr ""
+
+#: templates/settings.php:40
+msgid "First day of the week"
+msgstr ""
+
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr ""
+
+#: templates/share.dropdown.php:20
+msgid "Users"
+msgstr ""
+
+#: templates/share.dropdown.php:21
+msgid "select users"
+msgstr ""
+
+#: templates/share.dropdown.php:36 templates/share.dropdown.php:62
+msgid "Editable"
+msgstr ""
+
+#: templates/share.dropdown.php:48
+msgid "Groups"
+msgstr ""
+
+#: templates/share.dropdown.php:49
+msgid "select groups"
+msgstr ""
+
+#: templates/share.dropdown.php:75
+msgid "make public"
+msgstr ""
diff --git a/l10n/so/contacts.po b/l10n/so/contacts.po
new file mode 100644
index 00000000000..c5aa568cb39
--- /dev/null
+++ b/l10n/so/contacts.po
@@ -0,0 +1,871 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
+msgid "Error (de)activating addressbook."
+msgstr ""
+
+#: ajax/addcontact.php:47
+msgid "There was an error adding the contact."
+msgstr ""
+
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr ""
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr ""
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr ""
+
+#: ajax/addproperty.php:56
+msgid "Cannot add empty property."
+msgstr ""
+
+#: ajax/addproperty.php:67
+msgid "At least one of the address fields has to be filled out."
+msgstr ""
+
+#: ajax/addproperty.php:76
+msgid "Trying to add duplicate property: "
+msgstr ""
+
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:17
+msgid "No ID provided"
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:34
+msgid "Error setting checksum."
+msgstr ""
+
+#: ajax/categories/delete.php:19
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: ajax/categories/delete.php:26
+msgid "No address books found."
+msgstr ""
+
+#: ajax/categories/delete.php:34
+msgid "No contacts found."
+msgstr ""
+
+#: ajax/contactdetails.php:31
+msgid "Missing ID"
+msgstr ""
+
+#: ajax/contactdetails.php:36
+msgid "Error parsing VCard for ID: \""
+msgstr ""
+
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
+#: ajax/uploadphoto.php:68
+msgid "No contact ID was submitted."
+msgstr ""
+
+#: ajax/currentphoto.php:36
+msgid "Error reading contact photo."
+msgstr ""
+
+#: ajax/currentphoto.php:48
+msgid "Error saving temporary file."
+msgstr ""
+
+#: ajax/currentphoto.php:51
+msgid "The loading photo is not valid."
+msgstr ""
+
+#: ajax/deleteproperty.php:36
+msgid "Information about vCard is incorrect. Please reload the page."
+msgstr ""
+
+#: ajax/deleteproperty.php:43
+msgid "Error deleting contact property."
+msgstr ""
+
+#: ajax/editname.php:31
+msgid "Contact ID is missing."
+msgstr ""
+
+#: ajax/oc_photo.php:32
+msgid "No photo path was submitted."
+msgstr ""
+
+#: ajax/oc_photo.php:39
+msgid "File doesn't exist:"
+msgstr ""
+
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
+msgid "Error loading image."
+msgstr ""
+
+#: ajax/savecrop.php:67
+msgid "Error getting contact object."
+msgstr ""
+
+#: ajax/savecrop.php:76
+msgid "Error getting PHOTO property."
+msgstr ""
+
+#: ajax/savecrop.php:93
+msgid "Error saving contact."
+msgstr ""
+
+#: ajax/savecrop.php:103
+msgid "Error resizing image"
+msgstr ""
+
+#: ajax/savecrop.php:106
+msgid "Error cropping image"
+msgstr ""
+
+#: ajax/savecrop.php:109
+msgid "Error creating temporary image"
+msgstr ""
+
+#: ajax/savecrop.php:112
+msgid "Error finding image: "
+msgstr ""
+
+#: ajax/saveproperty.php:40
+msgid "checksum is not set."
+msgstr ""
+
+#: ajax/saveproperty.php:59
+msgid "Information about vCard is incorrect. Please reload the page: "
+msgstr ""
+
+#: ajax/saveproperty.php:64
+msgid "Something went FUBAR. "
+msgstr ""
+
+#: ajax/saveproperty.php:133
+msgid "Error updating contact property."
+msgstr ""
+
+#: ajax/updateaddressbook.php:21
+msgid "Cannot update addressbook with an empty name."
+msgstr ""
+
+#: ajax/updateaddressbook.php:25
+msgid "Error updating addressbook."
+msgstr ""
+
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
+msgid "Error uploading contacts to storage."
+msgstr ""
+
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
+msgid "Couldn't save temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
+msgid "Couldn't load temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:71
+msgid "No file was uploaded. Unknown error"
+msgstr ""
+
+#: appinfo/app.php:19 templates/settings.php:3
+msgid "Contacts"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Sorry, this functionality has not been implemented yet"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Not implemented"
+msgstr ""
+
+#: js/contacts.js:58
+msgid "Couldn't get a valid address."
+msgstr ""
+
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
+msgid "Error"
+msgstr ""
+
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New Contact"
+msgstr ""
+
+#: js/contacts.js:691
+msgid "This property has to be non-empty."
+msgstr ""
+
+#: js/contacts.js:717
+msgid "Couldn't serialize elements."
+msgstr ""
+
+#: js/contacts.js:826 js/contacts.js:844
+msgid ""
+"'deleteProperty' called without type argument. Please report at "
+"bugs.owncloud.org"
+msgstr ""
+
+#: js/contacts.js:860
+msgid "Edit name"
+msgstr ""
+
+#: js/contacts.js:1141
+msgid "No files selected for upload."
+msgstr ""
+
+#: js/contacts.js:1149
+msgid ""
+"The file you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: js/contacts.js:1314 js/contacts.js:1348
+msgid "Select type"
+msgstr ""
+
+#: js/loader.js:49
+msgid "Result: "
+msgstr ""
+
+#: js/loader.js:49
+msgid " imported, "
+msgstr ""
+
+#: js/loader.js:49
+msgid " failed."
+msgstr ""
+
+#: lib/app.php:29
+msgid "Addressbook not found."
+msgstr ""
+
+#: lib/app.php:33
+msgid "This is not your addressbook."
+msgstr ""
+
+#: lib/app.php:44
+msgid "Contact could not be found."
+msgstr ""
+
+#: lib/app.php:100 templates/part.contact.php:116
+msgid "Address"
+msgstr ""
+
+#: lib/app.php:101
+msgid "Telephone"
+msgstr ""
+
+#: lib/app.php:102 templates/part.contact.php:115
+msgid "Email"
+msgstr ""
+
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
+msgid "Organization"
+msgstr ""
+
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
+msgid "Work"
+msgstr ""
+
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
+msgid "Home"
+msgstr ""
+
+#: lib/app.php:121
+msgid "Mobile"
+msgstr ""
+
+#: lib/app.php:123
+msgid "Text"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Voice"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Message"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Fax"
+msgstr ""
+
+#: lib/app.php:127
+msgid "Video"
+msgstr ""
+
+#: lib/app.php:128
+msgid "Pager"
+msgstr ""
+
+#: lib/app.php:134
+msgid "Internet"
+msgstr ""
+
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
+msgstr ""
+
+#: lib/app.php:170
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:171
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:172
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:179
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr ""
+
+#: lib/hooks.php:102
+msgid "{name}'s Birthday"
+msgstr ""
+
+#: templates/index.php:15
+msgid "Add Contact"
+msgstr ""
+
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr ""
+
+#: templates/index.php:20
+msgid "Addressbooks"
+msgstr ""
+
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr ""
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr ""
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr ""
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr ""
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr ""
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr ""
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr ""
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr ""
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr ""
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:1
+msgid "Configure Address Books"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:16
+msgid "New Address Book"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:21
+#: templates/part.chooseaddressbook.rowfields.php:8
+msgid "CardDav Link"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:11
+msgid "Download"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:14
+msgid "Edit"
+msgstr ""
+
+#: templates/part.chooseaddressbook.rowfields.php:17
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
+msgid "Delete"
+msgstr ""
+
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
+msgstr ""
+
+#: templates/part.contact.php:18
+msgid "Delete current photo"
+msgstr ""
+
+#: templates/part.contact.php:19
+msgid "Edit current photo"
+msgstr ""
+
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr ""
+
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr ""
+
+#: templates/part.contact.php:34
+msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
+msgstr ""
+
+#: templates/part.contact.php:35
+msgid "Edit name details"
+msgstr ""
+
+#: templates/part.contact.php:40 templates/part.contact.php:112
+msgid "Nickname"
+msgstr ""
+
+#: templates/part.contact.php:41
+msgid "Enter nickname"
+msgstr ""
+
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr ""
+
+#: templates/part.contact.php:45
+msgid "dd-mm-yyyy"
+msgstr ""
+
+#: templates/part.contact.php:46 templates/part.contact.php:119
+msgid "Groups"
+msgstr ""
+
+#: templates/part.contact.php:48
+msgid "Separate groups with commas"
+msgstr ""
+
+#: templates/part.contact.php:49
+msgid "Edit groups"
+msgstr ""
+
+#: templates/part.contact.php:62 templates/part.contact.php:76
+msgid "Preferred"
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Please specify a valid email address."
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Enter email address"
+msgstr ""
+
+#: templates/part.contact.php:67
+msgid "Mail to address"
+msgstr ""
+
+#: templates/part.contact.php:68
+msgid "Delete email address"
+msgstr ""
+
+#: templates/part.contact.php:77
+msgid "Enter phone number"
+msgstr ""
+
+#: templates/part.contact.php:81
+msgid "Delete phone number"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "View on map"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "Edit address details"
+msgstr ""
+
+#: templates/part.contact.php:102
+msgid "Add notes here."
+msgstr ""
+
+#: templates/part.contact.php:109
+msgid "Add field"
+msgstr ""
+
+#: templates/part.contact.php:114
+msgid "Phone"
+msgstr ""
+
+#: templates/part.contact.php:117
+msgid "Note"
+msgstr ""
+
+#: templates/part.contact.php:122
+msgid "Download contact"
+msgstr ""
+
+#: templates/part.contact.php:123
+msgid "Delete contact"
+msgstr ""
+
+#: templates/part.cropphoto.php:65
+msgid "The temporary image has been removed from cache."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:6
+msgid "Edit address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:10
+msgid "Type"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
+msgid "PO Box"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:30
+msgid "Extended"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
+msgid "City"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:42
+msgid "Region"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:48
+msgid "Zipcode"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
+msgid "Country"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:16
+msgid "Addressbook"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:23
+msgid "Hon. prefixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:27
+msgid "Miss"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:28
+msgid "Ms"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:29
+msgid "Mr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:30
+msgid "Sir"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:31
+msgid "Mrs"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:32
+msgid "Dr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:35
+msgid "Given name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:37
+msgid "Additional names"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:39
+msgid "Family name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:41
+msgid "Hon. suffixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:45
+msgid "J.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:46
+msgid "M.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:47
+msgid "D.O."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:48
+msgid "D.C."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:49
+msgid "Ph.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:50
+msgid "Esq."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:51
+msgid "Jr."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:52
+msgid "Sn."
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "New Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "Edit Addressbook"
+msgstr ""
+
+#: templates/part.editaddressbook.php:12
+msgid "Displayname"
+msgstr ""
+
+#: templates/part.editaddressbook.php:23
+msgid "Active"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Save"
+msgstr ""
+
+#: templates/part.editaddressbook.php:29
+msgid "Submit"
+msgstr ""
+
+#: templates/part.editaddressbook.php:30
+msgid "Cancel"
+msgstr ""
+
+#: templates/part.import.php:1
+msgid "Import a contacts file"
+msgstr ""
+
+#: templates/part.import.php:6
+msgid "Please choose the addressbook"
+msgstr ""
+
+#: templates/part.import.php:10
+msgid "create a new addressbook"
+msgstr ""
+
+#: templates/part.import.php:15
+msgid "Name of new addressbook"
+msgstr ""
+
+#: templates/part.import.php:20
+msgid "Importing contacts"
+msgstr ""
+
+#: templates/part.no_contacts.php:2
+msgid "You have no contacts in your addressbook."
+msgstr ""
+
+#: templates/part.no_contacts.php:4
+msgid "Add contact"
+msgstr ""
+
+#: templates/part.no_contacts.php:5
+msgid "Configure addressbooks"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "CardDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:6
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:8
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr ""
diff --git a/l10n/so/core.po b/l10n/so/core.po
new file mode 100644
index 00000000000..17556c7d3e8
--- /dev/null
+++ b/l10n/so/core.po
@@ -0,0 +1,268 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:28+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/vcategories/add.php:23 ajax/vcategories/delete.php:23
+msgid "Application name not provided."
+msgstr ""
+
+#: ajax/vcategories/add.php:29
+msgid "No category to add?"
+msgstr ""
+
+#: ajax/vcategories/add.php:36
+msgid "This category already exists: "
+msgstr ""
+
+#: js/jquery-ui-1.8.16.custom.min.js:511
+msgid "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
+msgstr ""
+
+#: js/js.js:519
+msgid "January"
+msgstr ""
+
+#: js/js.js:519
+msgid "February"
+msgstr ""
+
+#: js/js.js:519
+msgid "March"
+msgstr ""
+
+#: js/js.js:519
+msgid "April"
+msgstr ""
+
+#: js/js.js:519
+msgid "May"
+msgstr ""
+
+#: js/js.js:519
+msgid "June"
+msgstr ""
+
+#: js/js.js:520
+msgid "July"
+msgstr ""
+
+#: js/js.js:520
+msgid "August"
+msgstr ""
+
+#: js/js.js:520
+msgid "September"
+msgstr ""
+
+#: js/js.js:520
+msgid "October"
+msgstr ""
+
+#: js/js.js:520
+msgid "November"
+msgstr ""
+
+#: js/js.js:520
+msgid "December"
+msgstr ""
+
+#: js/oc-dialogs.js:143 js/oc-dialogs.js:163
+msgid "Cancel"
+msgstr ""
+
+#: js/oc-dialogs.js:159
+msgid "No"
+msgstr ""
+
+#: js/oc-dialogs.js:160
+msgid "Yes"
+msgstr ""
+
+#: js/oc-dialogs.js:177
+msgid "Ok"
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: js/oc-vcategories.js:68
+msgid "Error"
+msgstr ""
+
+#: lostpassword/index.php:26
+msgid "ownCloud password reset"
+msgstr ""
+
+#: lostpassword/templates/email.php:1
+msgid "Use the following link to reset your password: {link}"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:3
+msgid "You will receive a link to reset your password via Email."
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:5
+msgid "Requested"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:8
+msgid "Login failed!"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:11 templates/installation.php:25
+#: templates/login.php:9
+msgid "Username"
+msgstr ""
+
+#: lostpassword/templates/lostpassword.php:15
+msgid "Request reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:4
+msgid "Your password was reset"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:5
+msgid "To login page"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:8
+msgid "New password"
+msgstr ""
+
+#: lostpassword/templates/resetpassword.php:11
+msgid "Reset password"
+msgstr ""
+
+#: strings.php:5
+msgid "Personal"
+msgstr ""
+
+#: strings.php:6
+msgid "Users"
+msgstr ""
+
+#: strings.php:7
+msgid "Apps"
+msgstr ""
+
+#: strings.php:8
+msgid "Admin"
+msgstr ""
+
+#: strings.php:9
+msgid "Help"
+msgstr ""
+
+#: templates/403.php:12
+msgid "Access forbidden"
+msgstr ""
+
+#: templates/404.php:12
+msgid "Cloud not found"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:4
+msgid "Edit categories"
+msgstr ""
+
+#: templates/edit_categories_dialog.php:14
+msgid "Add"
+msgstr ""
+
+#: templates/installation.php:23
+msgid "Create an <strong>admin account</strong>"
+msgstr ""
+
+#: templates/installation.php:29 templates/login.php:13
+msgid "Password"
+msgstr ""
+
+#: templates/installation.php:35
+msgid "Advanced"
+msgstr ""
+
+#: templates/installation.php:37
+msgid "Data folder"
+msgstr ""
+
+#: templates/installation.php:44
+msgid "Configure the database"
+msgstr ""
+
+#: templates/installation.php:49 templates/installation.php:60
+#: templates/installation.php:70
+msgid "will be used"
+msgstr ""
+
+#: templates/installation.php:82
+msgid "Database user"
+msgstr ""
+
+#: templates/installation.php:86
+msgid "Database password"
+msgstr ""
+
+#: templates/installation.php:90
+msgid "Database name"
+msgstr ""
+
+#: templates/installation.php:96
+msgid "Database host"
+msgstr ""
+
+#: templates/installation.php:101
+msgid "Finish setup"
+msgstr ""
+
+#: templates/layout.guest.php:42
+msgid "web services under your control"
+msgstr ""
+
+#: templates/layout.user.php:49
+msgid "Log out"
+msgstr ""
+
+#: templates/layout.user.php:64 templates/layout.user.php:65
+msgid "Settings"
+msgstr ""
+
+#: templates/login.php:6
+msgid "Lost your password?"
+msgstr ""
+
+#: templates/login.php:17
+msgid "remember"
+msgstr ""
+
+#: templates/login.php:18
+msgid "Log in"
+msgstr ""
+
+#: templates/logout.php:1
+msgid "You are logged out."
+msgstr ""
+
+#: templates/part.pagenavi.php:3
+msgid "prev"
+msgstr ""
+
+#: templates/part.pagenavi.php:20
+msgid "next"
+msgstr ""
diff --git a/l10n/so/files.po b/l10n/so/files.po
new file mode 100644
index 00000000000..d4b3a6c136e
--- /dev/null
+++ b/l10n/so/files.po
@@ -0,0 +1,198 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/upload.php:20
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/upload.php:21
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/upload.php:22
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/upload.php:23
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/upload.php:24
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/upload.php:25
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/upload.php:26
+msgid "Failed to write to disk"
+msgstr ""
+
+#: appinfo/app.php:6
+msgid "Files"
+msgstr ""
+
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr ""
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr ""
+
+#: js/filelist.js:186
+msgid "undo deletion"
+msgstr ""
+
+#: js/files.js:170
+msgid "generating ZIP-file, it may take some time."
+msgstr ""
+
+#: js/files.js:199
+msgid "Unable to upload your file as it is a directory or has 0 bytes"
+msgstr ""
+
+#: js/files.js:199
+msgid "Upload Error"
+msgstr ""
+
+#: js/files.js:227 js/files.js:318 js/files.js:347
+msgid "Pending"
+msgstr ""
+
+#: js/files.js:332
+msgid "Upload cancelled."
+msgstr ""
+
+#: js/files.js:456
+msgid "Invalid name, '/' is not allowed."
+msgstr ""
+
+#: js/files.js:631 templates/index.php:55
+msgid "Size"
+msgstr ""
+
+#: js/files.js:632 templates/index.php:56
+msgid "Modified"
+msgstr ""
+
+#: js/files.js:659
+msgid "folder"
+msgstr ""
+
+#: js/files.js:661
+msgid "folders"
+msgstr ""
+
+#: js/files.js:669
+msgid "file"
+msgstr ""
+
+#: js/files.js:671
+msgid "files"
+msgstr ""
+
+#: templates/admin.php:5
+msgid "File handling"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "Maximum upload size"
+msgstr ""
+
+#: templates/admin.php:7
+msgid "max. possible: "
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Needed for multi-file and folder downloads."
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Enable ZIP-download"
+msgstr ""
+
+#: templates/admin.php:11
+msgid "0 is unlimited"
+msgstr ""
+
+#: templates/admin.php:12
+msgid "Maximum input size for ZIP files"
+msgstr ""
+
+#: templates/index.php:7
+msgid "New"
+msgstr ""
+
+#: templates/index.php:9
+msgid "Text file"
+msgstr ""
+
+#: templates/index.php:10
+msgid "Folder"
+msgstr ""
+
+#: templates/index.php:11
+msgid "From url"
+msgstr ""
+
+#: templates/index.php:21
+msgid "Upload"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Cancel upload"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Nothing in here. Upload something!"
+msgstr ""
+
+#: templates/index.php:47
+msgid "Name"
+msgstr ""
+
+#: templates/index.php:49
+msgid "Share"
+msgstr ""
+
+#: templates/index.php:51
+msgid "Download"
+msgstr ""
+
+#: templates/index.php:64
+msgid "Upload too large"
+msgstr ""
+
+#: templates/index.php:66
+msgid ""
+"The files you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: templates/index.php:71
+msgid "Files are being scanned, please wait."
+msgstr ""
+
+#: templates/index.php:74
+msgid "Current scanning"
+msgstr ""
diff --git a/l10n/so/gallery.po b/l10n/so/gallery.po
new file mode 100644
index 00000000000..e520c32b948
--- /dev/null
+++ b/l10n/so/gallery.po
@@ -0,0 +1,58 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: appinfo/app.php:39
+msgid "Pictures"
+msgstr ""
+
+#: js/pictures.js:12
+msgid "Share gallery"
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Error: "
+msgstr ""
+
+#: js/pictures.js:32
+msgid "Internal error"
+msgstr ""
+
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr ""
+
+#: templates/view_album.php:19
+msgid "Back"
+msgstr ""
+
+#: templates/view_album.php:36
+msgid "Remove confirmation"
+msgstr ""
+
+#: templates/view_album.php:37
+msgid "Do you want to remove album"
+msgstr ""
+
+#: templates/view_album.php:40
+msgid "Change album name"
+msgstr ""
+
+#: templates/view_album.php:43
+msgid "New album name"
+msgstr ""
diff --git a/l10n/so/media.po b/l10n/so/media.po
new file mode 100644
index 00000000000..ed91c8d409b
--- /dev/null
+++ b/l10n/so/media.po
@@ -0,0 +1,66 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2011-08-13 02:19+0000\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: appinfo/app.php:45 templates/player.php:8
+msgid "Music"
+msgstr ""
+
+#: js/music.js:18
+msgid "Add album to playlist"
+msgstr ""
+
+#: templates/music.php:3 templates/player.php:12
+msgid "Play"
+msgstr ""
+
+#: templates/music.php:4 templates/music.php:26 templates/player.php:13
+msgid "Pause"
+msgstr ""
+
+#: templates/music.php:5
+msgid "Previous"
+msgstr ""
+
+#: templates/music.php:6 templates/player.php:14
+msgid "Next"
+msgstr ""
+
+#: templates/music.php:7
+msgid "Mute"
+msgstr ""
+
+#: templates/music.php:8
+msgid "Unmute"
+msgstr ""
+
+#: templates/music.php:25
+msgid "Rescan Collection"
+msgstr ""
+
+#: templates/music.php:37
+msgid "Artist"
+msgstr ""
+
+#: templates/music.php:38
+msgid "Album"
+msgstr ""
+
+#: templates/music.php:39
+msgid "Title"
+msgstr ""
diff --git a/l10n/so/settings.po b/l10n/so/settings.po
new file mode 100644
index 00000000000..f505b8ba5e2
--- /dev/null
+++ b/l10n/so/settings.po
@@ -0,0 +1,206 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Somali (http://www.transifex.com/projects/p/owncloud/language/so/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: so\n"
+"Plural-Forms: nplurals=2; plural=(n != 1)\n"
+
+#: ajax/lostpassword.php:14
+msgid "Email saved"
+msgstr ""
+
+#: ajax/lostpassword.php:16
+msgid "Invalid email"
+msgstr ""
+
+#: ajax/openid.php:16
+msgid "OpenID Changed"
+msgstr ""
+
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
+msgid "Invalid request"
+msgstr ""
+
+#: ajax/setlanguage.php:18
+msgid "Language changed"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:67
+msgid "Disable"
+msgstr ""
+
+#: js/apps.js:31 js/apps.js:54
+msgid "Enable"
+msgstr ""
+
+#: js/personal.js:69
+msgid "Saving..."
+msgstr ""
+
+#: personal.php:41 personal.php:42
+msgid "__language_name__"
+msgstr ""
+
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr ""
+
+#: templates/admin.php:28
+msgid "Log"
+msgstr ""
+
+#: templates/admin.php:55
+msgid "More"
+msgstr ""
+
+#: templates/apps.php:10
+msgid "Add your App"
+msgstr ""
+
+#: templates/apps.php:24
+msgid "Select an App"
+msgstr ""
+
+#: templates/apps.php:27
+msgid "See application page at apps.owncloud.com"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "-licensed"
+msgstr ""
+
+#: templates/apps.php:28
+msgid "by"
+msgstr ""
+
+#: templates/help.php:8
+msgid "Documentation"
+msgstr ""
+
+#: templates/help.php:9
+msgid "Managing Big Files"
+msgstr ""
+
+#: templates/help.php:10
+msgid "Ask a question"
+msgstr ""
+
+#: templates/help.php:22
+msgid "Problems connecting to help database."
+msgstr ""
+
+#: templates/help.php:23
+msgid "Go there manually."
+msgstr ""
+
+#: templates/help.php:31
+msgid "Answer"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "You use"
+msgstr ""
+
+#: templates/personal.php:8
+msgid "of the available"
+msgstr ""
+
+#: templates/personal.php:12
+msgid "Desktop and Mobile Syncing Clients"
+msgstr ""
+
+#: templates/personal.php:13
+msgid "Download"
+msgstr ""
+
+#: templates/personal.php:19
+msgid "Your password got changed"
+msgstr ""
+
+#: templates/personal.php:20
+msgid "Unable to change your password"
+msgstr ""
+
+#: templates/personal.php:21
+msgid "Current password"
+msgstr ""
+
+#: templates/personal.php:22
+msgid "New password"
+msgstr ""
+
+#: templates/personal.php:23
+msgid "show"
+msgstr ""
+
+#: templates/personal.php:24
+msgid "Change password"
+msgstr ""
+
+#: templates/personal.php:30
+msgid "Email"
+msgstr ""
+
+#: templates/personal.php:31
+msgid "Your email address"
+msgstr ""
+
+#: templates/personal.php:32
+msgid "Fill in an email address to enable password recovery"
+msgstr ""
+
+#: templates/personal.php:38 templates/personal.php:39
+msgid "Language"
+msgstr ""
+
+#: templates/personal.php:44
+msgid "Help translate"
+msgstr ""
+
+#: templates/personal.php:51
+msgid "use this address to connect to your ownCloud in your file manager"
+msgstr ""
+
+#: templates/users.php:15 templates/users.php:60
+msgid "Name"
+msgstr ""
+
+#: templates/users.php:17 templates/users.php:61
+msgid "Password"
+msgstr ""
+
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
+msgid "Groups"
+msgstr ""
+
+#: templates/users.php:25
+msgid "Create"
+msgstr ""
+
+#: templates/users.php:28
+msgid "Default Quota"
+msgstr ""
+
+#: templates/users.php:47 templates/users.php:103
+msgid "Other"
+msgstr ""
+
+#: templates/users.php:63
+msgid "Quota"
+msgstr ""
+
+#: templates/users.php:110
+msgid "Delete"
+msgstr ""
diff --git a/l10n/templates/bookmarks.pot b/l10n/templates/bookmarks.pot
index a55aacd8701..1ee9f5a85a6 100644
--- a/l10n/templates/bookmarks.pot
+++ b/l10n/templates/bookmarks.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -21,7 +21,7 @@ msgstr ""
msgid "Bookmarks"
msgstr ""
-#: bookmarksHelper.php:98
+#: bookmarksHelper.php:99
msgid "unnamed"
msgstr ""
diff --git a/l10n/templates/calendar.pot b/l10n/templates/calendar.pot
index bab10467584..eb31c594a8d 100644
--- a/l10n/templates/calendar.pot
+++ b/l10n/templates/calendar.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,11 +17,19 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ajax/categories/rescan.php:28
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
msgid "No calendars found."
msgstr ""
-#: ajax/categories/rescan.php:36
+#: ajax/categories/rescan.php:37
msgid "No events found."
msgstr ""
@@ -29,28 +37,42 @@ msgstr ""
msgid "Wrong calendar"
msgstr ""
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr ""
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
#: ajax/settings/guesstimezone.php:25
msgid "New Timezone:"
msgstr ""
-#: ajax/settings/settimezone.php:22
+#: ajax/settings/settimezone.php:23
msgid "Timezone changed"
msgstr ""
-#: ajax/settings/settimezone.php:24
+#: ajax/settings/settimezone.php:25
msgid "Invalid request"
msgstr ""
-#: appinfo/app.php:19 templates/calendar.php:15
-#: templates/part.eventform.php:33 templates/part.showevent.php:31
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
#: templates/settings.php:12
msgid "Calendar"
msgstr ""
-#: js/calendar.js:93
-msgid "Deletion failed"
-msgstr ""
-
#: js/calendar.js:828
msgid "ddd"
msgstr ""
@@ -75,252 +97,333 @@ msgstr ""
msgid "dddd, MMM d, yyyy"
msgstr ""
-#: lib/app.php:125
+#: lib/app.php:121
msgid "Birthday"
msgstr ""
-#: lib/app.php:126
+#: lib/app.php:122
msgid "Business"
msgstr ""
-#: lib/app.php:127
+#: lib/app.php:123
msgid "Call"
msgstr ""
-#: lib/app.php:128
+#: lib/app.php:124
msgid "Clients"
msgstr ""
-#: lib/app.php:129
+#: lib/app.php:125
msgid "Deliverer"
msgstr ""
-#: lib/app.php:130
+#: lib/app.php:126
msgid "Holidays"
msgstr ""
-#: lib/app.php:131
+#: lib/app.php:127
msgid "Ideas"
msgstr ""
-#: lib/app.php:132
+#: lib/app.php:128
msgid "Journey"
msgstr ""
-#: lib/app.php:133
+#: lib/app.php:129
msgid "Jubilee"
msgstr ""
-#: lib/app.php:134
+#: lib/app.php:130
msgid "Meeting"
msgstr ""
-#: lib/app.php:135
+#: lib/app.php:131
msgid "Other"
msgstr ""
-#: lib/app.php:136
+#: lib/app.php:132
msgid "Personal"
msgstr ""
-#: lib/app.php:137
+#: lib/app.php:133
msgid "Projects"
msgstr ""
-#: lib/app.php:138
+#: lib/app.php:134
msgid "Questions"
msgstr ""
-#: lib/app.php:139
+#: lib/app.php:135
msgid "Work"
msgstr ""
-#: lib/app.php:380
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr ""
+
+#: lib/app.php:359 lib/app.php:399
msgid "unnamed"
msgstr ""
-#: lib/object.php:330
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr ""
+
+#: lib/object.php:372
msgid "Does not repeat"
msgstr ""
-#: lib/object.php:331
+#: lib/object.php:373
msgid "Daily"
msgstr ""
-#: lib/object.php:332
+#: lib/object.php:374
msgid "Weekly"
msgstr ""
-#: lib/object.php:333
+#: lib/object.php:375
msgid "Every Weekday"
msgstr ""
-#: lib/object.php:334
+#: lib/object.php:376
msgid "Bi-Weekly"
msgstr ""
-#: lib/object.php:335
+#: lib/object.php:377
msgid "Monthly"
msgstr ""
-#: lib/object.php:336
+#: lib/object.php:378
msgid "Yearly"
msgstr ""
-#: lib/object.php:343
+#: lib/object.php:388
msgid "never"
msgstr ""
-#: lib/object.php:344
+#: lib/object.php:389
msgid "by occurrences"
msgstr ""
-#: lib/object.php:345
+#: lib/object.php:390
msgid "by date"
msgstr ""
-#: lib/object.php:352
+#: lib/object.php:400
msgid "by monthday"
msgstr ""
-#: lib/object.php:353
+#: lib/object.php:401
msgid "by weekday"
msgstr ""
-#: lib/object.php:360 templates/settings.php:42
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
msgid "Monday"
msgstr ""
-#: lib/object.php:361
+#: lib/object.php:412 templates/calendar.php:5
msgid "Tuesday"
msgstr ""
-#: lib/object.php:362
+#: lib/object.php:413 templates/calendar.php:5
msgid "Wednesday"
msgstr ""
-#: lib/object.php:363
+#: lib/object.php:414 templates/calendar.php:5
msgid "Thursday"
msgstr ""
-#: lib/object.php:364
+#: lib/object.php:415 templates/calendar.php:5
msgid "Friday"
msgstr ""
-#: lib/object.php:365
+#: lib/object.php:416 templates/calendar.php:5
msgid "Saturday"
msgstr ""
-#: lib/object.php:366 templates/settings.php:43
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
msgid "Sunday"
msgstr ""
-#: lib/object.php:373
+#: lib/object.php:427
msgid "events week of month"
msgstr ""
-#: lib/object.php:374
+#: lib/object.php:428
msgid "first"
msgstr ""
-#: lib/object.php:375
+#: lib/object.php:429
msgid "second"
msgstr ""
-#: lib/object.php:376
+#: lib/object.php:430
msgid "third"
msgstr ""
-#: lib/object.php:377
+#: lib/object.php:431
msgid "fourth"
msgstr ""
-#: lib/object.php:378
+#: lib/object.php:432
msgid "fifth"
msgstr ""
-#: lib/object.php:379
+#: lib/object.php:433
msgid "last"
msgstr ""
-#: lib/object.php:401
+#: lib/object.php:467 templates/calendar.php:7
msgid "January"
msgstr ""
-#: lib/object.php:402
+#: lib/object.php:468 templates/calendar.php:7
msgid "February"
msgstr ""
-#: lib/object.php:403
+#: lib/object.php:469 templates/calendar.php:7
msgid "March"
msgstr ""
-#: lib/object.php:404
+#: lib/object.php:470 templates/calendar.php:7
msgid "April"
msgstr ""
-#: lib/object.php:405
+#: lib/object.php:471 templates/calendar.php:7
msgid "May"
msgstr ""
-#: lib/object.php:406
+#: lib/object.php:472 templates/calendar.php:7
msgid "June"
msgstr ""
-#: lib/object.php:407
+#: lib/object.php:473 templates/calendar.php:7
msgid "July"
msgstr ""
-#: lib/object.php:408
+#: lib/object.php:474 templates/calendar.php:7
msgid "August"
msgstr ""
-#: lib/object.php:409
+#: lib/object.php:475 templates/calendar.php:7
msgid "September"
msgstr ""
-#: lib/object.php:410
+#: lib/object.php:476 templates/calendar.php:7
msgid "October"
msgstr ""
-#: lib/object.php:411
+#: lib/object.php:477 templates/calendar.php:7
msgid "November"
msgstr ""
-#: lib/object.php:412
+#: lib/object.php:478 templates/calendar.php:7
msgid "December"
msgstr ""
-#: lib/object.php:418
+#: lib/object.php:488
msgid "by events date"
msgstr ""
-#: lib/object.php:419
+#: lib/object.php:489
msgid "by yearday(s)"
msgstr ""
-#: lib/object.php:420
+#: lib/object.php:490
msgid "by weeknumber(s)"
msgstr ""
-#: lib/object.php:421
+#: lib/object.php:491
msgid "by day and month"
msgstr ""
-#: lib/search.php:32 lib/search.php:34 lib/search.php:37
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
msgid "Date"
msgstr ""
-#: lib/search.php:40
+#: lib/search.php:43
msgid "Cal."
msgstr ""
-#: templates/calendar.php:11
-msgid "All day"
+#: templates/calendar.php:6
+msgid "Sun."
msgstr ""
-#: templates/calendar.php:12 templates/part.choosecalendar.php:22
-msgid "New Calendar"
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr ""
+
+#: templates/calendar.php:11
+msgid "All day"
msgstr ""
#: templates/calendar.php:13
@@ -356,27 +459,27 @@ msgstr ""
msgid "There was a database fail"
msgstr ""
-#: templates/calendar.php:40
+#: templates/calendar.php:38
msgid "Week"
msgstr ""
-#: templates/calendar.php:41
+#: templates/calendar.php:39
msgid "Month"
msgstr ""
-#: templates/calendar.php:42
+#: templates/calendar.php:40
msgid "List"
msgstr ""
-#: templates/calendar.php:48
+#: templates/calendar.php:44
msgid "Today"
msgstr ""
-#: templates/calendar.php:49
+#: templates/calendar.php:45
msgid "Calendars"
msgstr ""
-#: templates/calendar.php:67
+#: templates/calendar.php:59
msgid "There was a fail, while parsing the file."
msgstr ""
@@ -389,7 +492,7 @@ msgid "Your calendars"
msgstr ""
#: templates/part.choosecalendar.php:27
-#: templates/part.choosecalendar.rowfields.php:5
+#: templates/part.choosecalendar.rowfields.php:11
msgid "CalDav Link"
msgstr ""
@@ -401,19 +504,19 @@ msgstr ""
msgid "No shared calendars"
msgstr ""
-#: templates/part.choosecalendar.rowfields.php:4
+#: templates/part.choosecalendar.rowfields.php:8
msgid "Share Calendar"
msgstr ""
-#: templates/part.choosecalendar.rowfields.php:6
+#: templates/part.choosecalendar.rowfields.php:14
msgid "Download"
msgstr ""
-#: templates/part.choosecalendar.rowfields.php:7
+#: templates/part.choosecalendar.rowfields.php:17
msgid "Edit"
msgstr ""
-#: templates/part.choosecalendar.rowfields.php:8
+#: templates/part.choosecalendar.rowfields.php:20
#: templates/part.editevent.php:9
msgid "Delete"
msgstr ""
@@ -499,23 +602,23 @@ msgstr ""
msgid "Edit categories"
msgstr ""
-#: templates/part.eventform.php:56 templates/part.showevent.php:55
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
msgid "All Day Event"
msgstr ""
-#: templates/part.eventform.php:60 templates/part.showevent.php:59
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
msgid "From"
msgstr ""
-#: templates/part.eventform.php:68 templates/part.showevent.php:67
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
msgid "To"
msgstr ""
-#: templates/part.eventform.php:76 templates/part.showevent.php:75
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
msgid "Advanced options"
msgstr ""
-#: templates/part.eventform.php:81 templates/part.showevent.php:80
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
msgid "Location"
msgstr ""
@@ -523,7 +626,7 @@ msgstr ""
msgid "Location of the Event"
msgstr ""
-#: templates/part.eventform.php:89 templates/part.showevent.php:88
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
msgid "Description"
msgstr ""
@@ -531,84 +634,86 @@ msgstr ""
msgid "Description of the Event"
msgstr ""
-#: templates/part.eventform.php:100 templates/part.showevent.php:98
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
msgid "Repeat"
msgstr ""
-#: templates/part.eventform.php:107 templates/part.showevent.php:105
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
msgid "Advanced"
msgstr ""
-#: templates/part.eventform.php:151 templates/part.showevent.php:149
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
msgid "Select weekdays"
msgstr ""
#: templates/part.eventform.php:164 templates/part.eventform.php:177
-#: templates/part.showevent.php:162 templates/part.showevent.php:175
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
msgid "Select days"
msgstr ""
-#: templates/part.eventform.php:169 templates/part.showevent.php:167
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
msgid "and the events day of year."
msgstr ""
-#: templates/part.eventform.php:182 templates/part.showevent.php:180
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
msgid "and the events day of month."
msgstr ""
-#: templates/part.eventform.php:190 templates/part.showevent.php:188
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
msgid "Select months"
msgstr ""
-#: templates/part.eventform.php:203 templates/part.showevent.php:201
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
msgid "Select weeks"
msgstr ""
-#: templates/part.eventform.php:208 templates/part.showevent.php:206
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
msgid "and the events week of year."
msgstr ""
-#: templates/part.eventform.php:214 templates/part.showevent.php:212
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
msgid "Interval"
msgstr ""
-#: templates/part.eventform.php:220 templates/part.showevent.php:218
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
msgid "End"
msgstr ""
-#: templates/part.eventform.php:233 templates/part.showevent.php:231
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
msgid "occurrences"
msgstr ""
-#: templates/part.import.php:1
-msgid "Import a calendar file"
+#: templates/part.import.php:14
+msgid "create a new calendar"
msgstr ""
-#: templates/part.import.php:6
-msgid "Please choose the calendar"
+#: templates/part.import.php:17
+msgid "Import a calendar file"
msgstr ""
-#: templates/part.import.php:10
-msgid "create a new calendar"
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
msgstr ""
-#: templates/part.import.php:15
+#: templates/part.import.php:36
msgid "Name of new calendar"
msgstr ""
-#: templates/part.import.php:17
-msgid "Import"
+#: templates/part.import.php:44
+msgid "Take an available name!"
msgstr ""
-#: templates/part.import.php:20
-msgid "Importing calendar"
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
msgstr ""
-#: templates/part.import.php:23
-msgid "Calendar imported successfully"
+#: templates/part.import.php:47
+msgid "Import"
msgstr ""
-#: templates/part.import.php:24
+#: templates/part.import.php:56
msgid "Close Dialog"
msgstr ""
@@ -624,15 +729,11 @@ msgstr ""
msgid "No categories selected"
msgstr ""
-#: templates/part.showevent.php:25
-msgid "Select category"
-msgstr ""
-
#: templates/part.showevent.php:37
msgid "of"
msgstr ""
-#: templates/part.showevent.php:62 templates/part.showevent.php:70
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
msgid "at"
msgstr ""
@@ -660,8 +761,32 @@ msgstr ""
msgid "First day of the week"
msgstr ""
-#: templates/settings.php:49
-msgid "Calendar CalDAV syncing address:"
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
msgstr ""
#: templates/share.dropdown.php:20
diff --git a/l10n/templates/contacts.pot b/l10n/templates/contacts.pot
index 15859a85e53..6b03be705cc 100644
--- a/l10n/templates/contacts.pot
+++ b/l10n/templates/contacts.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,91 +17,87 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ajax/activation.php:19 ajax/updateaddressbook.php:32
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
msgid "Error (de)activating addressbook."
msgstr ""
-#: ajax/addcontact.php:59
+#: ajax/addcontact.php:47
msgid "There was an error adding the contact."
msgstr ""
-#: ajax/addproperty.php:40
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr ""
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr ""
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr ""
+
+#: ajax/addproperty.php:56
msgid "Cannot add empty property."
msgstr ""
-#: ajax/addproperty.php:52
+#: ajax/addproperty.php:67
msgid "At least one of the address fields has to be filled out."
msgstr ""
-#: ajax/addproperty.php:62
+#: ajax/addproperty.php:76
msgid "Trying to add duplicate property: "
msgstr ""
-#: ajax/addproperty.php:120
-msgid "Error adding contact property."
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
msgstr ""
-#: ajax/categories/categoriesfor.php:15
+#: ajax/categories/categoriesfor.php:17
msgid "No ID provided"
msgstr ""
-#: ajax/categories/categoriesfor.php:27
+#: ajax/categories/categoriesfor.php:34
msgid "Error setting checksum."
msgstr ""
-#: ajax/categories/delete.php:29
+#: ajax/categories/delete.php:19
msgid "No categories selected for deletion."
msgstr ""
-#: ajax/categories/delete.php:36 ajax/categories/rescan.php:28
+#: ajax/categories/delete.php:26
msgid "No address books found."
msgstr ""
-#: ajax/categories/delete.php:44 ajax/categories/rescan.php:36
+#: ajax/categories/delete.php:34
msgid "No contacts found."
msgstr ""
-#: ajax/contactdetails.php:37
+#: ajax/contactdetails.php:31
msgid "Missing ID"
msgstr ""
-#: ajax/contactdetails.php:41
+#: ajax/contactdetails.php:36
msgid "Error parsing VCard for ID: \""
msgstr ""
-#: ajax/createaddressbook.php:18
-msgid "Cannot add addressbook with an empty name."
-msgstr ""
-
-#: ajax/createaddressbook.php:24
-msgid "Error adding addressbook."
-msgstr ""
-
-#: ajax/createaddressbook.php:30
-msgid "Error activating addressbook."
-msgstr ""
-
-#: ajax/currentphoto.php:34 ajax/oc_photo.php:37 ajax/uploadphoto.php:41
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
#: ajax/uploadphoto.php:68
msgid "No contact ID was submitted."
msgstr ""
-#: ajax/currentphoto.php:40
+#: ajax/currentphoto.php:36
msgid "Error reading contact photo."
msgstr ""
-#: ajax/currentphoto.php:52
+#: ajax/currentphoto.php:48
msgid "Error saving temporary file."
msgstr ""
-#: ajax/currentphoto.php:55
+#: ajax/currentphoto.php:51
msgid "The loading photo is not valid."
msgstr ""
-#: ajax/deletecard.php:37 ajax/saveproperty.php:58
-msgid "id is not set."
-msgstr ""
-
#: ajax/deleteproperty.php:36
msgid "Information about vCard is incorrect. Please reload the page."
msgstr ""
@@ -110,117 +106,109 @@ msgstr ""
msgid "Error deleting contact property."
msgstr ""
-#: ajax/editname.php:37
+#: ajax/editname.php:31
msgid "Contact ID is missing."
msgstr ""
-#: ajax/loadphoto.php:44
-msgid "Missing contact id."
-msgstr ""
-
-#: ajax/oc_photo.php:41
+#: ajax/oc_photo.php:32
msgid "No photo path was submitted."
msgstr ""
-#: ajax/oc_photo.php:48
+#: ajax/oc_photo.php:39
msgid "File doesn't exist:"
msgstr ""
-#: ajax/oc_photo.php:54 ajax/oc_photo.php:57
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
msgid "Error loading image."
msgstr ""
-#: ajax/savecrop.php:68
+#: ajax/savecrop.php:67
msgid "Error getting contact object."
msgstr ""
-#: ajax/savecrop.php:75
+#: ajax/savecrop.php:76
msgid "Error getting PHOTO property."
msgstr ""
-#: ajax/savecrop.php:88
+#: ajax/savecrop.php:93
msgid "Error saving contact."
msgstr ""
-#: ajax/savecrop.php:98
+#: ajax/savecrop.php:103
msgid "Error resizing image"
msgstr ""
-#: ajax/savecrop.php:101
+#: ajax/savecrop.php:106
msgid "Error cropping image"
msgstr ""
-#: ajax/savecrop.php:104
+#: ajax/savecrop.php:109
msgid "Error creating temporary image"
msgstr ""
-#: ajax/savecrop.php:107
+#: ajax/savecrop.php:112
msgid "Error finding image: "
msgstr ""
-#: ajax/saveproperty.php:55
-msgid "element name is not set."
-msgstr ""
-
-#: ajax/saveproperty.php:61
+#: ajax/saveproperty.php:40
msgid "checksum is not set."
msgstr ""
-#: ajax/saveproperty.php:78
+#: ajax/saveproperty.php:59
msgid "Information about vCard is incorrect. Please reload the page: "
msgstr ""
-#: ajax/saveproperty.php:83
+#: ajax/saveproperty.php:64
msgid "Something went FUBAR. "
msgstr ""
-#: ajax/saveproperty.php:150
+#: ajax/saveproperty.php:133
msgid "Error updating contact property."
msgstr ""
-#: ajax/updateaddressbook.php:20
+#: ajax/updateaddressbook.php:21
msgid "Cannot update addressbook with an empty name."
msgstr ""
-#: ajax/updateaddressbook.php:26
+#: ajax/updateaddressbook.php:25
msgid "Error updating addressbook."
msgstr ""
-#: ajax/uploadimport.php:46 ajax/uploadimport.php:76
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
msgid "Error uploading contacts to storage."
msgstr ""
-#: ajax/uploadimport.php:59 ajax/uploadphoto.php:77
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
msgid "There is no error, the file uploaded with success"
msgstr ""
-#: ajax/uploadimport.php:60 ajax/uploadphoto.php:78
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
msgstr ""
-#: ajax/uploadimport.php:61 ajax/uploadphoto.php:79
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
msgid ""
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
"the HTML form"
msgstr ""
-#: ajax/uploadimport.php:62 ajax/uploadphoto.php:80
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
msgid "The uploaded file was only partially uploaded"
msgstr ""
-#: ajax/uploadimport.php:63 ajax/uploadphoto.php:81
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
msgid "No file was uploaded"
msgstr ""
-#: ajax/uploadimport.php:64 ajax/uploadphoto.php:82
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
msgid "Missing a temporary folder"
msgstr ""
-#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:102
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
msgid "Couldn't save temporary image: "
msgstr ""
-#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:105
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
msgid "Couldn't load temporary image: "
msgstr ""
@@ -228,113 +216,75 @@ msgstr ""
msgid "No file was uploaded. Unknown error"
msgstr ""
-#: appinfo/app.php:17 templates/settings.php:3
+#: appinfo/app.php:19 templates/settings.php:3
msgid "Contacts"
msgstr ""
-#: js/contacts.js:24
+#: js/contacts.js:53
msgid "Sorry, this functionality has not been implemented yet"
msgstr ""
-#: js/contacts.js:24
+#: js/contacts.js:53
msgid "Not implemented"
msgstr ""
-#: js/contacts.js:29
+#: js/contacts.js:58
msgid "Couldn't get a valid address."
msgstr ""
-#: js/contacts.js:29 js/contacts.js:334 js/contacts.js:341 js/contacts.js:355
-#: js/contacts.js:393 js/contacts.js:399 js/contacts.js:565 js/contacts.js:605
-#: js/contacts.js:631 js/contacts.js:668 js/contacts.js:747 js/contacts.js:753
-#: js/contacts.js:765 js/contacts.js:799 js/contacts.js:1056
-#: js/contacts.js:1064 js/contacts.js:1073 js/contacts.js:1130
-#: js/contacts.js:1146 js/contacts.js:1161 js/contacts.js:1173
-#: js/contacts.js:1196 js/contacts.js:1449 js/contacts.js:1457
-#: js/contacts.js:1483 js/contacts.js:1494 js/contacts.js:1509
-#: js/contacts.js:1526 js/contacts.js:1596 js/contacts.js:1644
-#: js/contacts.js:1654 js/contacts.js:1657
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
msgid "Error"
msgstr ""
-#: js/contacts.js:364
-msgid "Are you sure you want to delete this contact?"
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New"
msgstr ""
-#: js/contacts.js:364
-msgid "Warning"
+#: js/contacts.js:389
+msgid "New Contact"
msgstr ""
-#: js/contacts.js:605
+#: js/contacts.js:691
msgid "This property has to be non-empty."
msgstr ""
-#: js/contacts.js:631
+#: js/contacts.js:717
msgid "Couldn't serialize elements."
msgstr ""
-#: js/contacts.js:747 js/contacts.js:765
+#: js/contacts.js:826 js/contacts.js:844
msgid ""
"'deleteProperty' called without type argument. Please report at bugs."
"owncloud.org"
msgstr ""
-#: js/contacts.js:781
+#: js/contacts.js:860
msgid "Edit name"
msgstr ""
-#: js/contacts.js:1056
+#: js/contacts.js:1141
msgid "No files selected for upload."
msgstr ""
-#: js/contacts.js:1064 js/contacts.js:1449 js/contacts.js:1634
+#: js/contacts.js:1149
msgid ""
"The file you are trying to upload exceed the maximum size for file uploads "
"on this server."
msgstr ""
-#: js/contacts.js:1119
-msgid "Select photo"
-msgstr ""
-
-#: js/contacts.js:1257 js/contacts.js:1290
+#: js/contacts.js:1314 js/contacts.js:1348
msgid "Select type"
msgstr ""
-#: js/contacts.js:1305 templates/part.importaddressbook.php:25
-msgid "Drop a VCF file to import contacts."
-msgstr ""
-
-#: js/contacts.js:1475
-msgid "Import done. Success/Failure: "
-msgstr ""
-
-#: js/contacts.js:1476
-msgid "OK"
-msgstr ""
-
-#: js/contacts.js:1494
-msgid "Displayname cannot be empty."
-msgstr ""
-
-#: js/contacts.js:1634
-msgid "Upload too large"
-msgstr ""
-
-#: js/contacts.js:1638
-msgid "Only image files can be used as profile picture."
-msgstr ""
-
-#: js/contacts.js:1638
-msgid "Wrong file type"
-msgstr ""
-
-#: js/contacts.js:1644
-msgid ""
-"Your browser doesn't support AJAX upload. Please click on the profile "
-"picture to select a photo to upload."
-msgstr ""
-
#: js/loader.js:49
msgid "Result: "
msgstr ""
@@ -347,91 +297,196 @@ msgstr ""
msgid " failed."
msgstr ""
-#: lib/app.php:30
+#: lib/app.php:29
msgid "Addressbook not found."
msgstr ""
-#: lib/app.php:34
+#: lib/app.php:33
msgid "This is not your addressbook."
msgstr ""
-#: lib/app.php:45
+#: lib/app.php:44
msgid "Contact could not be found."
msgstr ""
-#: lib/app.php:101 templates/part.contact.php:109
+#: lib/app.php:100 templates/part.contact.php:116
msgid "Address"
msgstr ""
-#: lib/app.php:102
+#: lib/app.php:101
msgid "Telephone"
msgstr ""
-#: lib/app.php:103 templates/part.contact.php:108
+#: lib/app.php:102 templates/part.contact.php:115
msgid "Email"
msgstr ""
-#: lib/app.php:104 templates/part.contact.php:33 templates/part.contact.php:34
-#: templates/part.contact.php:104
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
msgid "Organization"
msgstr ""
-#: lib/app.php:116 lib/app.php:123 lib/app.php:133
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
msgid "Work"
msgstr ""
-#: lib/app.php:117 lib/app.php:121 lib/app.php:134
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
msgid "Home"
msgstr ""
-#: lib/app.php:122
+#: lib/app.php:121
msgid "Mobile"
msgstr ""
-#: lib/app.php:124
+#: lib/app.php:123
msgid "Text"
msgstr ""
-#: lib/app.php:125
+#: lib/app.php:124
msgid "Voice"
msgstr ""
-#: lib/app.php:126
+#: lib/app.php:125
msgid "Message"
msgstr ""
-#: lib/app.php:127
+#: lib/app.php:126
msgid "Fax"
msgstr ""
-#: lib/app.php:128
+#: lib/app.php:127
msgid "Video"
msgstr ""
-#: lib/app.php:129
+#: lib/app.php:128
msgid "Pager"
msgstr ""
-#: lib/app.php:135
+#: lib/app.php:134
msgid "Internet"
msgstr ""
-#: lib/hooks.php:79
-msgid "{name}'s Birthday"
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
msgstr ""
-#: lib/search.php:22
-msgid "Contact"
+#: lib/app.php:170
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:171
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:172
+msgid "Clients"
msgstr ""
-#: templates/index.php:13
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:179
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr ""
+
+#: lib/hooks.php:102
+msgid "{name}'s Birthday"
+msgstr ""
+
+#: templates/index.php:15
msgid "Add Contact"
msgstr ""
-#: templates/index.php:14
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr ""
+
+#: templates/index.php:20
msgid "Addressbooks"
msgstr ""
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr ""
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr ""
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr ""
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr ""
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr ""
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr ""
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr ""
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr ""
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr ""
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr ""
+
#: templates/part.chooseaddressbook.php:1
msgid "Configure Address Books"
msgstr ""
@@ -440,11 +495,7 @@ msgstr ""
msgid "New Address Book"
msgstr ""
-#: templates/part.chooseaddressbook.php:17
-msgid "Import from VCF"
-msgstr ""
-
-#: templates/part.chooseaddressbook.php:22
+#: templates/part.chooseaddressbook.php:21
#: templates/part.chooseaddressbook.rowfields.php:8
msgid "CardDav Link"
msgstr ""
@@ -458,184 +509,193 @@ msgid "Edit"
msgstr ""
#: templates/part.chooseaddressbook.rowfields.php:17
-#: templates/part.contact.php:34 templates/part.contact.php:36
-#: templates/part.contact.php:38 templates/part.contact.php:42
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
msgid "Delete"
msgstr ""
-#: templates/part.contact.php:12
-msgid "Download contact"
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
msgstr ""
-#: templates/part.contact.php:13
-msgid "Delete contact"
+#: templates/part.contact.php:18
+msgid "Delete current photo"
msgstr ""
#: templates/part.contact.php:19
-msgid "Drop photo to upload"
+msgid "Edit current photo"
msgstr ""
-#: templates/part.contact.php:29
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr ""
+
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr ""
+
+#: templates/part.contact.php:34
msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
msgstr ""
-#: templates/part.contact.php:30
+#: templates/part.contact.php:35
msgid "Edit name details"
msgstr ""
-#: templates/part.contact.php:35 templates/part.contact.php:105
+#: templates/part.contact.php:40 templates/part.contact.php:112
msgid "Nickname"
msgstr ""
-#: templates/part.contact.php:36
+#: templates/part.contact.php:41
msgid "Enter nickname"
msgstr ""
-#: templates/part.contact.php:37 templates/part.contact.php:106
-msgid "Birthday"
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
msgstr ""
-#: templates/part.contact.php:38
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr ""
+
+#: templates/part.contact.php:45
msgid "dd-mm-yyyy"
msgstr ""
-#: templates/part.contact.php:39 templates/part.contact.php:111
+#: templates/part.contact.php:46 templates/part.contact.php:119
msgid "Groups"
msgstr ""
-#: templates/part.contact.php:41
+#: templates/part.contact.php:48
msgid "Separate groups with commas"
msgstr ""
-#: templates/part.contact.php:42
+#: templates/part.contact.php:49
msgid "Edit groups"
msgstr ""
-#: templates/part.contact.php:55 templates/part.contact.php:69
+#: templates/part.contact.php:62 templates/part.contact.php:76
msgid "Preferred"
msgstr ""
-#: templates/part.contact.php:56
+#: templates/part.contact.php:63
msgid "Please specify a valid email address."
msgstr ""
-#: templates/part.contact.php:56
+#: templates/part.contact.php:63
msgid "Enter email address"
msgstr ""
-#: templates/part.contact.php:60
+#: templates/part.contact.php:67
msgid "Mail to address"
msgstr ""
-#: templates/part.contact.php:61
+#: templates/part.contact.php:68
msgid "Delete email address"
msgstr ""
-#: templates/part.contact.php:70
+#: templates/part.contact.php:77
msgid "Enter phone number"
msgstr ""
-#: templates/part.contact.php:74
+#: templates/part.contact.php:81
msgid "Delete phone number"
msgstr ""
-#: templates/part.contact.php:84
+#: templates/part.contact.php:91
msgid "View on map"
msgstr ""
-#: templates/part.contact.php:84
+#: templates/part.contact.php:91
msgid "Edit address details"
msgstr ""
-#: templates/part.contact.php:95
+#: templates/part.contact.php:102
msgid "Add notes here."
msgstr ""
-#: templates/part.contact.php:101
+#: templates/part.contact.php:109
msgid "Add field"
msgstr ""
-#: templates/part.contact.php:103
-msgid "Profile picture"
-msgstr ""
-
-#: templates/part.contact.php:107
+#: templates/part.contact.php:114
msgid "Phone"
msgstr ""
-#: templates/part.contact.php:110
+#: templates/part.contact.php:117
msgid "Note"
msgstr ""
-#: templates/part.contactphoto.php:8
-msgid "Delete current photo"
-msgstr ""
-
-#: templates/part.contactphoto.php:9
-msgid "Edit current photo"
-msgstr ""
-
-#: templates/part.contactphoto.php:10
-msgid "Upload new photo"
+#: templates/part.contact.php:122
+msgid "Download contact"
msgstr ""
-#: templates/part.contactphoto.php:11
-msgid "Select photo from ownCloud"
+#: templates/part.contact.php:123
+msgid "Delete contact"
msgstr ""
-#: templates/part.cropphoto.php:64
+#: templates/part.cropphoto.php:65
msgid "The temporary image has been removed from cache."
msgstr ""
-#: templates/part.edit_address_dialog.php:9
+#: templates/part.edit_address_dialog.php:6
msgid "Edit address"
msgstr ""
-#: templates/part.edit_address_dialog.php:14
+#: templates/part.edit_address_dialog.php:10
msgid "Type"
msgstr ""
-#: templates/part.edit_address_dialog.php:22
-#: templates/part.edit_address_dialog.php:25
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
msgid "PO Box"
msgstr ""
-#: templates/part.edit_address_dialog.php:29
-#: templates/part.edit_address_dialog.php:32
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:30
msgid "Extended"
msgstr ""
-#: templates/part.edit_address_dialog.php:35
-#: templates/part.edit_address_dialog.php:38
-msgid "Street"
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
msgstr ""
-#: templates/part.edit_address_dialog.php:41
-#: templates/part.edit_address_dialog.php:44
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
msgid "City"
msgstr ""
-#: templates/part.edit_address_dialog.php:47
-#: templates/part.edit_address_dialog.php:50
+#: templates/part.edit_address_dialog.php:42
msgid "Region"
msgstr ""
-#: templates/part.edit_address_dialog.php:53
-#: templates/part.edit_address_dialog.php:56
-msgid "Zipcode"
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
msgstr ""
-#: templates/part.edit_address_dialog.php:59
-#: templates/part.edit_address_dialog.php:62
-msgid "Country"
+#: templates/part.edit_address_dialog.php:48
+msgid "Zipcode"
msgstr ""
-#: templates/part.edit_categories_dialog.php:4
-msgid "Edit categories"
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
msgstr ""
-#: templates/part.edit_categories_dialog.php:14
-msgid "Add"
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
+msgid "Country"
msgstr ""
#: templates/part.edit_name_dialog.php:16
@@ -743,7 +803,6 @@ msgid "Submit"
msgstr ""
#: templates/part.editaddressbook.php:30
-#: templates/part.importaddressbook.php:34
msgid "Cancel"
msgstr ""
@@ -763,32 +822,10 @@ msgstr ""
msgid "Name of new addressbook"
msgstr ""
-#: templates/part.import.php:17
-msgid "Import"
-msgstr ""
-
#: templates/part.import.php:20
msgid "Importing contacts"
msgstr ""
-#: templates/part.import.php:24
-msgid "Close"
-msgstr ""
-
-#: templates/part.importaddressbook.php:12
-msgid ""
-"Currently this import function doesn't work while encryption is enabled.<br /"
-">Please upload your VCF file with the file manager and click on it to import."
-msgstr ""
-
-#: templates/part.importaddressbook.php:16
-msgid "Select address book to import to:"
-msgstr ""
-
-#: templates/part.importaddressbook.php:26
-msgid "Select from HD"
-msgstr ""
-
#: templates/part.no_contacts.php:2
msgid "You have no contacts in your addressbook."
msgstr ""
@@ -801,6 +838,18 @@ msgstr ""
msgid "Configure addressbooks"
msgstr ""
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr ""
+
#: templates/settings.php:4
msgid "CardDAV syncing addresses"
msgstr ""
@@ -816,3 +865,7 @@ msgstr ""
#: templates/settings.php:8
msgid "iOS/OS X"
msgstr ""
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr ""
diff --git a/l10n/templates/core.pot b/l10n/templates/core.pot
index 46ee521dfa0..e19f8059280 100644
--- a/l10n/templates/core.pot
+++ b/l10n/templates/core.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -33,51 +33,51 @@ msgstr ""
msgid "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "January"
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "February"
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "March"
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "April"
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "May"
msgstr ""
-#: js/js.js:520
+#: js/js.js:519
msgid "June"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "July"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "August"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "September"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "October"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "November"
msgstr ""
-#: js/js.js:521
+#: js/js.js:520
msgid "December"
msgstr ""
@@ -106,10 +106,6 @@ msgid "Error"
msgstr ""
#: lostpassword/index.php:26
-msgid "Owncloud password reset"
-msgstr ""
-
-#: lostpassword/index.php:27
msgid "ownCloud password reset"
msgstr ""
@@ -239,11 +235,11 @@ msgstr ""
msgid "web services under your control"
msgstr ""
-#: templates/layout.user.php:41
+#: templates/layout.user.php:49
msgid "Log out"
msgstr ""
-#: templates/layout.user.php:53 templates/layout.user.php:54
+#: templates/layout.user.php:64 templates/layout.user.php:65
msgid "Settings"
msgstr ""
diff --git a/l10n/templates/files.pot b/l10n/templates/files.pot
index d38e5942c2e..7c8581071cb 100644
--- a/l10n/templates/files.pot
+++ b/l10n/templates/files.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,33 +17,33 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: ajax/upload.php:19
+#: ajax/upload.php:20
msgid "There is no error, the file uploaded with success"
msgstr ""
-#: ajax/upload.php:20
+#: ajax/upload.php:21
msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
msgstr ""
-#: ajax/upload.php:21
+#: ajax/upload.php:22
msgid ""
"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
"the HTML form"
msgstr ""
-#: ajax/upload.php:22
+#: ajax/upload.php:23
msgid "The uploaded file was only partially uploaded"
msgstr ""
-#: ajax/upload.php:23
+#: ajax/upload.php:24
msgid "No file was uploaded"
msgstr ""
-#: ajax/upload.php:24
+#: ajax/upload.php:25
msgid "Missing a temporary folder"
msgstr ""
-#: ajax/upload.php:25
+#: ajax/upload.php:26
msgid "Failed to write to disk"
msgstr ""
@@ -51,6 +51,14 @@ msgstr ""
msgid "Files"
msgstr ""
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr ""
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr ""
+
#: js/filelist.js:186
msgid "undo deletion"
msgstr ""
@@ -79,27 +87,27 @@ msgstr ""
msgid "Invalid name, '/' is not allowed."
msgstr ""
-#: js/files.js:626 templates/index.php:55
+#: js/files.js:631 templates/index.php:55
msgid "Size"
msgstr ""
-#: js/files.js:627 templates/index.php:56
+#: js/files.js:632 templates/index.php:56
msgid "Modified"
msgstr ""
-#: js/files.js:654
+#: js/files.js:659
msgid "folder"
msgstr ""
-#: js/files.js:656
+#: js/files.js:661
msgid "folders"
msgstr ""
-#: js/files.js:664
+#: js/files.js:669
msgid "file"
msgstr ""
-#: js/files.js:666
+#: js/files.js:671
msgid "files"
msgstr ""
@@ -171,10 +179,6 @@ msgstr ""
msgid "Download"
msgstr ""
-#: templates/index.php:56
-msgid "Delete"
-msgstr ""
-
#: templates/index.php:64
msgid "Upload too large"
msgstr ""
diff --git a/l10n/templates/gallery.pot b/l10n/templates/gallery.pot
index 0cf2a7db970..e0f819f9dff 100644
--- a/l10n/templates/gallery.pot
+++ b/l10n/templates/gallery.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,60 +17,24 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: appinfo/app.php:37
+#: appinfo/app.php:39
msgid "Pictures"
msgstr ""
-#: js/album_cover.js:44
+#: js/pictures.js:12
msgid "Share gallery"
msgstr ""
-#: js/album_cover.js:64 js/album_cover.js:100 js/album_cover.js:133
+#: js/pictures.js:32
msgid "Error: "
msgstr ""
-#: js/album_cover.js:64 js/album_cover.js:100
+#: js/pictures.js:32
msgid "Internal error"
msgstr ""
-#: js/album_cover.js:114
-msgid "Scanning root"
-msgstr ""
-
-#: js/album_cover.js:115
-msgid "Default order"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Ascending"
-msgstr ""
-
-#: js/album_cover.js:116
-msgid "Descending"
-msgstr ""
-
-#: js/album_cover.js:117 templates/index.php:19
-msgid "Settings"
-msgstr ""
-
-#: js/album_cover.js:122
-msgid "Scanning root cannot be empty"
-msgstr ""
-
-#: js/album_cover.js:122 js/album_cover.js:133
-msgid "Error"
-msgstr ""
-
-#: templates/index.php:16
-msgid "Rescan"
-msgstr ""
-
-#: templates/index.php:17
-msgid "Stop"
-msgstr ""
-
-#: templates/index.php:18
-msgid "Share"
+#: templates/index.php:27
+msgid "Slideshow"
msgstr ""
#: templates/view_album.php:19
diff --git a/l10n/templates/lib.pot b/l10n/templates/lib.pot
new file mode 100644
index 00000000000..410e16d9dce
--- /dev/null
+++ b/l10n/templates/lib.pot
@@ -0,0 +1,112 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
+#
+#, fuzzy
+msgid ""
+msgstr ""
+"Project-Id-Version: PACKAGE VERSION\n"
+"Report-Msgid-Bugs-To: \n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
+"Language-Team: LANGUAGE <LL@li.org>\n"
+"Language: \n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=CHARSET\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#: app.php:287
+msgid "Help"
+msgstr ""
+
+#: app.php:294
+msgid "Personal"
+msgstr ""
+
+#: app.php:299
+msgid "Settings"
+msgstr ""
+
+#: app.php:304
+msgid "Users"
+msgstr ""
+
+#: app.php:306
+msgid "Apps"
+msgstr ""
+
+#: app.php:308
+msgid "Admin"
+msgstr ""
+
+#: files.php:245
+msgid "ZIP download is turned off."
+msgstr ""
+
+#: files.php:246
+msgid "Files need to be downloaded one by one."
+msgstr ""
+
+#: files.php:246 files.php:271
+msgid "Back to Files"
+msgstr ""
+
+#: files.php:270
+msgid "Selected files too large to generate zip file."
+msgstr ""
+
+#: json.php:28
+msgid "Application is not enabled"
+msgstr ""
+
+#: json.php:39 json.php:63
+msgid "Authentication error"
+msgstr ""
+
+#: json.php:51
+msgid "Token expired. Please reload page."
+msgstr ""
+
+#: template.php:86
+msgid "seconds ago"
+msgstr ""
+
+#: template.php:87
+msgid "1 minute ago"
+msgstr ""
+
+#: template.php:88
+#, php-format
+msgid "%d minutes ago"
+msgstr ""
+
+#: template.php:91
+msgid "today"
+msgstr ""
+
+#: template.php:92
+msgid "yesterday"
+msgstr ""
+
+#: template.php:93
+#, php-format
+msgid "%d days ago"
+msgstr ""
+
+#: template.php:94
+msgid "last month"
+msgstr ""
+
+#: template.php:95
+msgid "months ago"
+msgstr ""
+
+#: template.php:96
+msgid "last year"
+msgstr ""
+
+#: template.php:97
+msgid "years ago"
+msgstr ""
diff --git a/l10n/templates/media.pot b/l10n/templates/media.pot
index b722f87d435..6406b0120e5 100644
--- a/l10n/templates/media.pot
+++ b/l10n/templates/media.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -17,7 +17,7 @@ msgstr ""
"Content-Type: text/plain; charset=CHARSET\n"
"Content-Transfer-Encoding: 8bit\n"
-#: appinfo/app.php:32 templates/player.php:8
+#: appinfo/app.php:45 templates/player.php:8
msgid "Music"
msgstr ""
diff --git a/l10n/templates/settings.pot b/l10n/templates/settings.pot
index 85b693c5c01..e8d0757e9f9 100644
--- a/l10n/templates/settings.pot
+++ b/l10n/templates/settings.pot
@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2012-06-06 00:12+0200\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -25,15 +25,15 @@ msgstr ""
msgid "Invalid email"
msgstr ""
-#: ajax/openid.php:15
+#: ajax/openid.php:16
msgid "OpenID Changed"
msgstr ""
-#: ajax/openid.php:17 ajax/setlanguage.php:19 ajax/setlanguage.php:22
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
msgid "Invalid request"
msgstr ""
-#: ajax/setlanguage.php:17
+#: ajax/setlanguage.php:18
msgid "Language changed"
msgstr ""
@@ -49,35 +49,39 @@ msgstr ""
msgid "Saving..."
msgstr ""
-#: personal.php:40 personal.php:41
+#: personal.php:41 personal.php:42
msgid "__language_name__"
msgstr ""
-#: templates/admin.php:13
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr ""
+
+#: templates/admin.php:28
msgid "Log"
msgstr ""
-#: templates/admin.php:40
+#: templates/admin.php:55
msgid "More"
msgstr ""
-#: templates/apps.php:8
+#: templates/apps.php:10
msgid "Add your App"
msgstr ""
-#: templates/apps.php:22
+#: templates/apps.php:24
msgid "Select an App"
msgstr ""
-#: templates/apps.php:25
+#: templates/apps.php:27
msgid "See application page at apps.owncloud.com"
msgstr ""
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "-licensed"
msgstr ""
-#: templates/apps.php:26
+#: templates/apps.php:28
msgid "by"
msgstr ""
@@ -169,34 +173,34 @@ msgstr ""
msgid "use this address to connect to your ownCloud in your file manager"
msgstr ""
-#: templates/users.php:15 templates/users.php:44
+#: templates/users.php:15 templates/users.php:60
msgid "Name"
msgstr ""
-#: templates/users.php:16 templates/users.php:45
+#: templates/users.php:17 templates/users.php:61
msgid "Password"
msgstr ""
-#: templates/users.php:17 templates/users.php:46 templates/users.php:60
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
msgid "Groups"
msgstr ""
-#: templates/users.php:22
+#: templates/users.php:25
msgid "Create"
msgstr ""
-#: templates/users.php:25
+#: templates/users.php:28
msgid "Default Quota"
msgstr ""
-#: templates/users.php:35 templates/users.php:74
+#: templates/users.php:47 templates/users.php:103
msgid "Other"
msgstr ""
-#: templates/users.php:47
+#: templates/users.php:63
msgid "Quota"
msgstr ""
-#: templates/users.php:80
+#: templates/users.php:110
msgid "Delete"
msgstr ""
diff --git a/l10n/vi/calendar.po b/l10n/vi/calendar.po
new file mode 100644
index 00000000000..f0f4660844a
--- /dev/null
+++ b/l10n/vi/calendar.po
@@ -0,0 +1,816 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# <mattheu_9x@yahoo.com>, 2012.
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/cache/status.php:19
+msgid "Not all calendars are completely cached"
+msgstr ""
+
+#: ajax/cache/status.php:21
+msgid "Everything seems to be completely cached"
+msgstr ""
+
+#: ajax/categories/rescan.php:29
+msgid "No calendars found."
+msgstr "Không tìm thấy lịch."
+
+#: ajax/categories/rescan.php:37
+msgid "No events found."
+msgstr "Không tìm thấy sự kiện nào"
+
+#: ajax/event/edit.form.php:20
+msgid "Wrong calendar"
+msgstr "Sai lịch"
+
+#: ajax/import/dropimport.php:29 ajax/import/import.php:64
+msgid ""
+"The file contained either no events or all events are already saved in your "
+"calendar."
+msgstr ""
+
+#: ajax/import/dropimport.php:31 ajax/import/import.php:67
+msgid "events has been saved in the new calendar"
+msgstr ""
+
+#: ajax/import/import.php:56
+msgid "Import failed"
+msgstr ""
+
+#: ajax/import/import.php:69
+msgid "events has been saved in your calendar"
+msgstr ""
+
+#: ajax/settings/guesstimezone.php:25
+msgid "New Timezone:"
+msgstr "Múi giờ mới :"
+
+#: ajax/settings/settimezone.php:23
+msgid "Timezone changed"
+msgstr "Thay đổi múi giờ"
+
+#: ajax/settings/settimezone.php:25
+msgid "Invalid request"
+msgstr "Yêu cầu không hợp lệ"
+
+#: appinfo/app.php:35 templates/calendar.php:15
+#: templates/part.eventform.php:33 templates/part.showevent.php:33
+#: templates/settings.php:12
+msgid "Calendar"
+msgstr "Lịch"
+
+#: js/calendar.js:828
+msgid "ddd"
+msgstr "ddd"
+
+#: js/calendar.js:829
+msgid "ddd M/d"
+msgstr "ddd M/d"
+
+#: js/calendar.js:830
+msgid "dddd M/d"
+msgstr "dddd M/d"
+
+#: js/calendar.js:833
+msgid "MMMM yyyy"
+msgstr "MMMM yyyy"
+
+#: js/calendar.js:835
+msgid "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
+msgstr "MMM d[ yyyy]{ '&#8212;'[ MMM] d yyyy}"
+
+#: js/calendar.js:837
+msgid "dddd, MMM d, yyyy"
+msgstr "dddd, MMM d, yyyy"
+
+#: lib/app.php:121
+msgid "Birthday"
+msgstr "Ngày sinh nhật"
+
+#: lib/app.php:122
+msgid "Business"
+msgstr "Công việc"
+
+#: lib/app.php:123
+msgid "Call"
+msgstr "Số điện thoại"
+
+#: lib/app.php:124
+msgid "Clients"
+msgstr "Máy trạm"
+
+#: lib/app.php:125
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Holidays"
+msgstr "Ngày lễ"
+
+#: lib/app.php:127
+msgid "Ideas"
+msgstr "Ý tưởng"
+
+#: lib/app.php:128
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:129
+msgid "Jubilee"
+msgstr "Lễ kỷ niệm"
+
+#: lib/app.php:130
+msgid "Meeting"
+msgstr "Hội nghị"
+
+#: lib/app.php:131
+msgid "Other"
+msgstr "Khác"
+
+#: lib/app.php:132
+msgid "Personal"
+msgstr "Cá nhân"
+
+#: lib/app.php:133
+msgid "Projects"
+msgstr "Dự án"
+
+#: lib/app.php:134
+msgid "Questions"
+msgstr "Câu hỏi"
+
+#: lib/app.php:135
+msgid "Work"
+msgstr "Công việc"
+
+#: lib/app.php:351 lib/app.php:361
+msgid "by"
+msgstr ""
+
+#: lib/app.php:359 lib/app.php:399
+msgid "unnamed"
+msgstr ""
+
+#: lib/import.php:184 templates/calendar.php:12
+#: templates/part.choosecalendar.php:22
+msgid "New Calendar"
+msgstr "Lịch mới"
+
+#: lib/object.php:372
+msgid "Does not repeat"
+msgstr "Không lặp lại"
+
+#: lib/object.php:373
+msgid "Daily"
+msgstr "Hàng ngày"
+
+#: lib/object.php:374
+msgid "Weekly"
+msgstr "Hàng tuần"
+
+#: lib/object.php:375
+msgid "Every Weekday"
+msgstr "Mỗi ngày trong tuần"
+
+#: lib/object.php:376
+msgid "Bi-Weekly"
+msgstr "Hai tuần một lần"
+
+#: lib/object.php:377
+msgid "Monthly"
+msgstr "Hàng tháng"
+
+#: lib/object.php:378
+msgid "Yearly"
+msgstr "Hàng năm"
+
+#: lib/object.php:388
+msgid "never"
+msgstr "không thay đổi"
+
+#: lib/object.php:389
+msgid "by occurrences"
+msgstr "bởi xuất hiện"
+
+#: lib/object.php:390
+msgid "by date"
+msgstr "bởi ngày"
+
+#: lib/object.php:400
+msgid "by monthday"
+msgstr "bởi ngày trong tháng"
+
+#: lib/object.php:401
+msgid "by weekday"
+msgstr "bởi ngày trong tuần"
+
+#: lib/object.php:411 templates/calendar.php:5 templates/settings.php:42
+msgid "Monday"
+msgstr "Thứ 2"
+
+#: lib/object.php:412 templates/calendar.php:5
+msgid "Tuesday"
+msgstr "Thứ 3"
+
+#: lib/object.php:413 templates/calendar.php:5
+msgid "Wednesday"
+msgstr "Thứ 4"
+
+#: lib/object.php:414 templates/calendar.php:5
+msgid "Thursday"
+msgstr "Thứ 5"
+
+#: lib/object.php:415 templates/calendar.php:5
+msgid "Friday"
+msgstr "Thứ "
+
+#: lib/object.php:416 templates/calendar.php:5
+msgid "Saturday"
+msgstr "Thứ 7"
+
+#: lib/object.php:417 templates/calendar.php:5 templates/settings.php:43
+msgid "Sunday"
+msgstr "Chủ nhật"
+
+#: lib/object.php:427
+msgid "events week of month"
+msgstr "sự kiện trong tuần của tháng"
+
+#: lib/object.php:428
+msgid "first"
+msgstr "đầu tiên"
+
+#: lib/object.php:429
+msgid "second"
+msgstr "Thứ hai"
+
+#: lib/object.php:430
+msgid "third"
+msgstr "Thứ ba"
+
+#: lib/object.php:431
+msgid "fourth"
+msgstr "Thứ tư"
+
+#: lib/object.php:432
+msgid "fifth"
+msgstr "Thứ năm"
+
+#: lib/object.php:433
+msgid "last"
+msgstr ""
+
+#: lib/object.php:467 templates/calendar.php:7
+msgid "January"
+msgstr "Tháng 1"
+
+#: lib/object.php:468 templates/calendar.php:7
+msgid "February"
+msgstr "Tháng 2"
+
+#: lib/object.php:469 templates/calendar.php:7
+msgid "March"
+msgstr "Tháng 3"
+
+#: lib/object.php:470 templates/calendar.php:7
+msgid "April"
+msgstr "Tháng 4"
+
+#: lib/object.php:471 templates/calendar.php:7
+msgid "May"
+msgstr "Tháng 5"
+
+#: lib/object.php:472 templates/calendar.php:7
+msgid "June"
+msgstr "Tháng 6"
+
+#: lib/object.php:473 templates/calendar.php:7
+msgid "July"
+msgstr "Tháng 7"
+
+#: lib/object.php:474 templates/calendar.php:7
+msgid "August"
+msgstr "Tháng 8"
+
+#: lib/object.php:475 templates/calendar.php:7
+msgid "September"
+msgstr "Tháng 9"
+
+#: lib/object.php:476 templates/calendar.php:7
+msgid "October"
+msgstr "Tháng 10"
+
+#: lib/object.php:477 templates/calendar.php:7
+msgid "November"
+msgstr "Tháng 11"
+
+#: lib/object.php:478 templates/calendar.php:7
+msgid "December"
+msgstr "Tháng 12"
+
+#: lib/object.php:488
+msgid "by events date"
+msgstr "Theo ngày tháng sự kiện"
+
+#: lib/object.php:489
+msgid "by yearday(s)"
+msgstr ""
+
+#: lib/object.php:490
+msgid "by weeknumber(s)"
+msgstr "số tuần"
+
+#: lib/object.php:491
+msgid "by day and month"
+msgstr "ngày, tháng"
+
+#: lib/search.php:35 lib/search.php:37 lib/search.php:40
+msgid "Date"
+msgstr "Ngày"
+
+#: lib/search.php:43
+msgid "Cal."
+msgstr "Cal."
+
+#: templates/calendar.php:6
+msgid "Sun."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Mon."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Tue."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Wed."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Thu."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Fri."
+msgstr ""
+
+#: templates/calendar.php:6
+msgid "Sat."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jan."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Feb."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Mar."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Apr."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "May."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jun."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Jul."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Aug."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Sep."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Oct."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Nov."
+msgstr ""
+
+#: templates/calendar.php:8
+msgid "Dec."
+msgstr ""
+
+#: templates/calendar.php:11
+msgid "All day"
+msgstr "Tất cả các ngày"
+
+#: templates/calendar.php:13
+msgid "Missing fields"
+msgstr ""
+
+#: templates/calendar.php:14 templates/part.eventform.php:19
+#: templates/part.showevent.php:11
+msgid "Title"
+msgstr "Tiêu đề"
+
+#: templates/calendar.php:16
+msgid "From Date"
+msgstr "Từ ngày"
+
+#: templates/calendar.php:17
+msgid "From Time"
+msgstr "Từ thời gian"
+
+#: templates/calendar.php:18
+msgid "To Date"
+msgstr "Tới ngày"
+
+#: templates/calendar.php:19
+msgid "To Time"
+msgstr "Tới thời gian"
+
+#: templates/calendar.php:20
+msgid "The event ends before it starts"
+msgstr "Sự kiện này kết thúc trước khi nó bắt đầu"
+
+#: templates/calendar.php:21
+msgid "There was a database fail"
+msgstr ""
+
+#: templates/calendar.php:38
+msgid "Week"
+msgstr "Tuần"
+
+#: templates/calendar.php:39
+msgid "Month"
+msgstr "Tháng"
+
+#: templates/calendar.php:40
+msgid "List"
+msgstr "Danh sách"
+
+#: templates/calendar.php:44
+msgid "Today"
+msgstr "Hôm nay"
+
+#: templates/calendar.php:45
+msgid "Calendars"
+msgstr "Lịch"
+
+#: templates/calendar.php:59
+msgid "There was a fail, while parsing the file."
+msgstr "Có một thất bại, trong khi phân tích các tập tin."
+
+#: templates/part.choosecalendar.php:1
+msgid "Choose active calendars"
+msgstr "Chọn lịch hoạt động"
+
+#: templates/part.choosecalendar.php:2
+msgid "Your calendars"
+msgstr "Lịch của bạn"
+
+#: templates/part.choosecalendar.php:27
+#: templates/part.choosecalendar.rowfields.php:11
+msgid "CalDav Link"
+msgstr "Liên kết CalDav "
+
+#: templates/part.choosecalendar.php:31
+msgid "Shared calendars"
+msgstr "Chia sẻ lịch"
+
+#: templates/part.choosecalendar.php:48
+msgid "No shared calendars"
+msgstr "Không chia sẻ lcihj"
+
+#: templates/part.choosecalendar.rowfields.php:8
+msgid "Share Calendar"
+msgstr "Chia sẻ lịch"
+
+#: templates/part.choosecalendar.rowfields.php:14
+msgid "Download"
+msgstr "Tải về"
+
+#: templates/part.choosecalendar.rowfields.php:17
+msgid "Edit"
+msgstr "Chỉnh sửa"
+
+#: templates/part.choosecalendar.rowfields.php:20
+#: templates/part.editevent.php:9
+msgid "Delete"
+msgstr "Xóa"
+
+#: templates/part.choosecalendar.rowfields.shared.php:4
+msgid "shared with you by"
+msgstr "Chia sẻ bởi"
+
+#: templates/part.editcalendar.php:9
+msgid "New calendar"
+msgstr "Lịch mới"
+
+#: templates/part.editcalendar.php:9
+msgid "Edit calendar"
+msgstr "sửa Lịch"
+
+#: templates/part.editcalendar.php:12
+msgid "Displayname"
+msgstr "Hiển thị tên"
+
+#: templates/part.editcalendar.php:23
+msgid "Active"
+msgstr "Kích hoạt"
+
+#: templates/part.editcalendar.php:29
+msgid "Calendar color"
+msgstr "Màu lịch"
+
+#: templates/part.editcalendar.php:42
+msgid "Save"
+msgstr "Lưu"
+
+#: templates/part.editcalendar.php:42 templates/part.editevent.php:8
+#: templates/part.newevent.php:6
+msgid "Submit"
+msgstr "Submit"
+
+#: templates/part.editcalendar.php:43
+msgid "Cancel"
+msgstr "Hủy"
+
+#: templates/part.editevent.php:1
+msgid "Edit an event"
+msgstr "Sửa sự kiện"
+
+#: templates/part.editevent.php:10
+msgid "Export"
+msgstr ""
+
+#: templates/part.eventform.php:8 templates/part.showevent.php:3
+msgid "Eventinfo"
+msgstr ""
+
+#: templates/part.eventform.php:9 templates/part.showevent.php:4
+msgid "Repeating"
+msgstr ""
+
+#: templates/part.eventform.php:10 templates/part.showevent.php:5
+msgid "Alarm"
+msgstr ""
+
+#: templates/part.eventform.php:11 templates/part.showevent.php:6
+msgid "Attendees"
+msgstr ""
+
+#: templates/part.eventform.php:13
+msgid "Share"
+msgstr "Chia sẻ"
+
+#: templates/part.eventform.php:21
+msgid "Title of the Event"
+msgstr "Tên sự kiện"
+
+#: templates/part.eventform.php:27 templates/part.showevent.php:19
+msgid "Category"
+msgstr "Danh mục"
+
+#: templates/part.eventform.php:29
+msgid "Separate categories with commas"
+msgstr ""
+
+#: templates/part.eventform.php:30
+msgid "Edit categories"
+msgstr ""
+
+#: templates/part.eventform.php:56 templates/part.showevent.php:52
+msgid "All Day Event"
+msgstr "Sự kiện trong ngày"
+
+#: templates/part.eventform.php:60 templates/part.showevent.php:56
+msgid "From"
+msgstr "Từ"
+
+#: templates/part.eventform.php:68 templates/part.showevent.php:64
+msgid "To"
+msgstr "Tới"
+
+#: templates/part.eventform.php:76 templates/part.showevent.php:72
+msgid "Advanced options"
+msgstr "Tùy chọn nâng cao"
+
+#: templates/part.eventform.php:81 templates/part.showevent.php:77
+msgid "Location"
+msgstr "Nơi"
+
+#: templates/part.eventform.php:83
+msgid "Location of the Event"
+msgstr "Nơi tổ chức sự kiện"
+
+#: templates/part.eventform.php:89 templates/part.showevent.php:85
+msgid "Description"
+msgstr "Mô tả"
+
+#: templates/part.eventform.php:91
+msgid "Description of the Event"
+msgstr "Mô tả sự kiện"
+
+#: templates/part.eventform.php:100 templates/part.showevent.php:95
+msgid "Repeat"
+msgstr "Lặp lại"
+
+#: templates/part.eventform.php:107 templates/part.showevent.php:102
+msgid "Advanced"
+msgstr "Nâng cao"
+
+#: templates/part.eventform.php:151 templates/part.showevent.php:146
+msgid "Select weekdays"
+msgstr "Chọn ngày trong tuần"
+
+#: templates/part.eventform.php:164 templates/part.eventform.php:177
+#: templates/part.showevent.php:159 templates/part.showevent.php:172
+msgid "Select days"
+msgstr "Chọn ngày"
+
+#: templates/part.eventform.php:169 templates/part.showevent.php:164
+msgid "and the events day of year."
+msgstr "và sự kiện của ngày trong năm"
+
+#: templates/part.eventform.php:182 templates/part.showevent.php:177
+msgid "and the events day of month."
+msgstr "và sự kiện của một ngày trong năm"
+
+#: templates/part.eventform.php:190 templates/part.showevent.php:185
+msgid "Select months"
+msgstr "Chọn tháng"
+
+#: templates/part.eventform.php:203 templates/part.showevent.php:198
+msgid "Select weeks"
+msgstr "Chọn tuần"
+
+#: templates/part.eventform.php:208 templates/part.showevent.php:203
+msgid "and the events week of year."
+msgstr "và sự kiện của tuần trong năm."
+
+#: templates/part.eventform.php:214 templates/part.showevent.php:209
+msgid "Interval"
+msgstr ""
+
+#: templates/part.eventform.php:220 templates/part.showevent.php:215
+msgid "End"
+msgstr ""
+
+#: templates/part.eventform.php:233 templates/part.showevent.php:228
+msgid "occurrences"
+msgstr ""
+
+#: templates/part.import.php:14
+msgid "create a new calendar"
+msgstr "Tạo lịch mới"
+
+#: templates/part.import.php:17
+msgid "Import a calendar file"
+msgstr ""
+
+#: templates/part.import.php:24
+msgid "Please choose a calendar"
+msgstr ""
+
+#: templates/part.import.php:36
+msgid "Name of new calendar"
+msgstr "Tên lịch mới"
+
+#: templates/part.import.php:44
+msgid "Take an available name!"
+msgstr ""
+
+#: templates/part.import.php:45
+msgid ""
+"A Calendar with this name already exists. If you continue anyhow, these "
+"calendars will be merged."
+msgstr ""
+
+#: templates/part.import.php:47
+msgid "Import"
+msgstr ""
+
+#: templates/part.import.php:56
+msgid "Close Dialog"
+msgstr "Đóng hộp thoại"
+
+#: templates/part.newevent.php:1
+msgid "Create a new event"
+msgstr "Tạo một sự kiện mới"
+
+#: templates/part.showevent.php:1
+msgid "View an event"
+msgstr "Xem một sự kiện"
+
+#: templates/part.showevent.php:23
+msgid "No categories selected"
+msgstr "Không danh sách nào được chọn"
+
+#: templates/part.showevent.php:37
+msgid "of"
+msgstr "của"
+
+#: templates/part.showevent.php:59 templates/part.showevent.php:67
+msgid "at"
+msgstr "tại"
+
+#: templates/settings.php:14
+msgid "Timezone"
+msgstr "Múi giờ"
+
+#: templates/settings.php:31
+msgid "Check always for changes of the timezone"
+msgstr "Luôn kiểm tra múi giờ"
+
+#: templates/settings.php:33
+msgid "Timeformat"
+msgstr ""
+
+#: templates/settings.php:35
+msgid "24h"
+msgstr "24h"
+
+#: templates/settings.php:36
+msgid "12h"
+msgstr "12h"
+
+#: templates/settings.php:40
+msgid "First day of the week"
+msgstr ""
+
+#: templates/settings.php:47
+msgid "Cache"
+msgstr ""
+
+#: templates/settings.php:48
+msgid "Clear cache for repeating events"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "Calendar CalDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:53
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:55
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:57
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:59
+msgid "Read only iCalendar link(s)"
+msgstr ""
+
+#: templates/share.dropdown.php:20
+msgid "Users"
+msgstr ""
+
+#: templates/share.dropdown.php:21
+msgid "select users"
+msgstr ""
+
+#: templates/share.dropdown.php:36 templates/share.dropdown.php:62
+msgid "Editable"
+msgstr ""
+
+#: templates/share.dropdown.php:48
+msgid "Groups"
+msgstr ""
+
+#: templates/share.dropdown.php:49
+msgid "select groups"
+msgstr ""
+
+#: templates/share.dropdown.php:75
+msgid "make public"
+msgstr ""
diff --git a/l10n/vi/contacts.po b/l10n/vi/contacts.po
new file mode 100644
index 00000000000..41383998b6b
--- /dev/null
+++ b/l10n/vi/contacts.po
@@ -0,0 +1,872 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/activation.php:24 ajax/updateaddressbook.php:29
+msgid "Error (de)activating addressbook."
+msgstr ""
+
+#: ajax/addcontact.php:47
+msgid "There was an error adding the contact."
+msgstr ""
+
+#: ajax/addproperty.php:39 ajax/saveproperty.php:34
+msgid "element name is not set."
+msgstr "tên phần tử không được thiết lập."
+
+#: ajax/addproperty.php:42 ajax/deletecard.php:30 ajax/saveproperty.php:37
+msgid "id is not set."
+msgstr "id không được thiết lập."
+
+#: ajax/addproperty.php:46
+msgid "Could not parse contact: "
+msgstr ""
+
+#: ajax/addproperty.php:56
+msgid "Cannot add empty property."
+msgstr ""
+
+#: ajax/addproperty.php:67
+msgid "At least one of the address fields has to be filled out."
+msgstr ""
+
+#: ajax/addproperty.php:76
+msgid "Trying to add duplicate property: "
+msgstr ""
+
+#: ajax/addproperty.php:144
+msgid "Error adding contact property: "
+msgstr ""
+
+#: ajax/categories/categoriesfor.php:17
+msgid "No ID provided"
+msgstr "Không có ID được cung cấp"
+
+#: ajax/categories/categoriesfor.php:34
+msgid "Error setting checksum."
+msgstr ""
+
+#: ajax/categories/delete.php:19
+msgid "No categories selected for deletion."
+msgstr ""
+
+#: ajax/categories/delete.php:26
+msgid "No address books found."
+msgstr "Không tìm thấy sổ địa chỉ."
+
+#: ajax/categories/delete.php:34
+msgid "No contacts found."
+msgstr "Không tìm thấy danh sách"
+
+#: ajax/contactdetails.php:31
+msgid "Missing ID"
+msgstr "Missing ID"
+
+#: ajax/contactdetails.php:36
+msgid "Error parsing VCard for ID: \""
+msgstr ""
+
+#: ajax/currentphoto.php:30 ajax/oc_photo.php:28 ajax/uploadphoto.php:36
+#: ajax/uploadphoto.php:68
+msgid "No contact ID was submitted."
+msgstr ""
+
+#: ajax/currentphoto.php:36
+msgid "Error reading contact photo."
+msgstr "Lỗi đọc liên lạc hình ảnh."
+
+#: ajax/currentphoto.php:48
+msgid "Error saving temporary file."
+msgstr ""
+
+#: ajax/currentphoto.php:51
+msgid "The loading photo is not valid."
+msgstr "Các hình ảnh tải không hợp lệ."
+
+#: ajax/deleteproperty.php:36
+msgid "Information about vCard is incorrect. Please reload the page."
+msgstr ""
+
+#: ajax/deleteproperty.php:43
+msgid "Error deleting contact property."
+msgstr ""
+
+#: ajax/editname.php:31
+msgid "Contact ID is missing."
+msgstr ""
+
+#: ajax/oc_photo.php:32
+msgid "No photo path was submitted."
+msgstr ""
+
+#: ajax/oc_photo.php:39
+msgid "File doesn't exist:"
+msgstr "Tập tin không tồn tại"
+
+#: ajax/oc_photo.php:44 ajax/oc_photo.php:47
+msgid "Error loading image."
+msgstr "Lỗi khi tải hình ảnh."
+
+#: ajax/savecrop.php:67
+msgid "Error getting contact object."
+msgstr ""
+
+#: ajax/savecrop.php:76
+msgid "Error getting PHOTO property."
+msgstr ""
+
+#: ajax/savecrop.php:93
+msgid "Error saving contact."
+msgstr ""
+
+#: ajax/savecrop.php:103
+msgid "Error resizing image"
+msgstr ""
+
+#: ajax/savecrop.php:106
+msgid "Error cropping image"
+msgstr ""
+
+#: ajax/savecrop.php:109
+msgid "Error creating temporary image"
+msgstr ""
+
+#: ajax/savecrop.php:112
+msgid "Error finding image: "
+msgstr ""
+
+#: ajax/saveproperty.php:40
+msgid "checksum is not set."
+msgstr ""
+
+#: ajax/saveproperty.php:59
+msgid "Information about vCard is incorrect. Please reload the page: "
+msgstr ""
+
+#: ajax/saveproperty.php:64
+msgid "Something went FUBAR. "
+msgstr ""
+
+#: ajax/saveproperty.php:133
+msgid "Error updating contact property."
+msgstr ""
+
+#: ajax/updateaddressbook.php:21
+msgid "Cannot update addressbook with an empty name."
+msgstr ""
+
+#: ajax/updateaddressbook.php:25
+msgid "Error updating addressbook."
+msgstr ""
+
+#: ajax/uploadimport.php:44 ajax/uploadimport.php:76
+msgid "Error uploading contacts to storage."
+msgstr "Lỗi tải lên danh sách địa chỉ để lưu trữ."
+
+#: ajax/uploadimport.php:61 ajax/uploadphoto.php:77
+msgid "There is no error, the file uploaded with success"
+msgstr "Không có lỗi, các tập tin tải lên thành công"
+
+#: ajax/uploadimport.php:62 ajax/uploadphoto.php:78
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/uploadimport.php:63 ajax/uploadphoto.php:79
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/uploadimport.php:64 ajax/uploadphoto.php:80
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:65 ajax/uploadphoto.php:81
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/uploadimport.php:66 ajax/uploadphoto.php:82
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/uploadphoto.php:59 ajax/uploadphoto.php:109
+msgid "Couldn't save temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:62 ajax/uploadphoto.php:112
+msgid "Couldn't load temporary image: "
+msgstr ""
+
+#: ajax/uploadphoto.php:71
+msgid "No file was uploaded. Unknown error"
+msgstr ""
+
+#: appinfo/app.php:19 templates/settings.php:3
+msgid "Contacts"
+msgstr "Liên lạc"
+
+#: js/contacts.js:53
+msgid "Sorry, this functionality has not been implemented yet"
+msgstr ""
+
+#: js/contacts.js:53
+msgid "Not implemented"
+msgstr ""
+
+#: js/contacts.js:58
+msgid "Couldn't get a valid address."
+msgstr ""
+
+#: js/contacts.js:58 js/contacts.js:347 js/contacts.js:363 js/contacts.js:376
+#: js/contacts.js:651 js/contacts.js:691 js/contacts.js:717 js/contacts.js:754
+#: js/contacts.js:826 js/contacts.js:832 js/contacts.js:844 js/contacts.js:878
+#: js/contacts.js:1141 js/contacts.js:1149 js/contacts.js:1158
+#: js/contacts.js:1193 js/contacts.js:1225 js/contacts.js:1237
+#: js/contacts.js:1260 js/contacts.js:1522
+msgid "Error"
+msgstr ""
+
+#: js/contacts.js:389 lib/search.php:15
+msgid "Contact"
+msgstr "Danh sách"
+
+#: js/contacts.js:389
+msgid "New"
+msgstr ""
+
+#: js/contacts.js:389
+msgid "New Contact"
+msgstr ""
+
+#: js/contacts.js:691
+msgid "This property has to be non-empty."
+msgstr ""
+
+#: js/contacts.js:717
+msgid "Couldn't serialize elements."
+msgstr ""
+
+#: js/contacts.js:826 js/contacts.js:844
+msgid ""
+"'deleteProperty' called without type argument. Please report at "
+"bugs.owncloud.org"
+msgstr ""
+
+#: js/contacts.js:860
+msgid "Edit name"
+msgstr ""
+
+#: js/contacts.js:1141
+msgid "No files selected for upload."
+msgstr ""
+
+#: js/contacts.js:1149
+msgid ""
+"The file you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: js/contacts.js:1314 js/contacts.js:1348
+msgid "Select type"
+msgstr ""
+
+#: js/loader.js:49
+msgid "Result: "
+msgstr ""
+
+#: js/loader.js:49
+msgid " imported, "
+msgstr ""
+
+#: js/loader.js:49
+msgid " failed."
+msgstr ""
+
+#: lib/app.php:29
+msgid "Addressbook not found."
+msgstr ""
+
+#: lib/app.php:33
+msgid "This is not your addressbook."
+msgstr ""
+
+#: lib/app.php:44
+msgid "Contact could not be found."
+msgstr ""
+
+#: lib/app.php:100 templates/part.contact.php:116
+msgid "Address"
+msgstr "Địa chỉ"
+
+#: lib/app.php:101
+msgid "Telephone"
+msgstr "Điện thoại bàn"
+
+#: lib/app.php:102 templates/part.contact.php:115
+msgid "Email"
+msgstr "Email"
+
+#: lib/app.php:103 templates/part.contact.php:38 templates/part.contact.php:39
+#: templates/part.contact.php:111
+msgid "Organization"
+msgstr "Tổ chức"
+
+#: lib/app.php:115 lib/app.php:122 lib/app.php:132 lib/app.php:183
+msgid "Work"
+msgstr "Công việc"
+
+#: lib/app.php:116 lib/app.php:120 lib/app.php:133
+msgid "Home"
+msgstr "Nhà"
+
+#: lib/app.php:121
+msgid "Mobile"
+msgstr "Di động"
+
+#: lib/app.php:123
+msgid "Text"
+msgstr ""
+
+#: lib/app.php:124
+msgid "Voice"
+msgstr ""
+
+#: lib/app.php:125
+msgid "Message"
+msgstr ""
+
+#: lib/app.php:126
+msgid "Fax"
+msgstr "Fax"
+
+#: lib/app.php:127
+msgid "Video"
+msgstr "Video"
+
+#: lib/app.php:128
+msgid "Pager"
+msgstr "số trang"
+
+#: lib/app.php:134
+msgid "Internet"
+msgstr ""
+
+#: lib/app.php:169 templates/part.contact.php:44
+#: templates/part.contact.php:113
+msgid "Birthday"
+msgstr "Ngày sinh nhật"
+
+#: lib/app.php:170
+msgid "Business"
+msgstr ""
+
+#: lib/app.php:171
+msgid "Call"
+msgstr ""
+
+#: lib/app.php:172
+msgid "Clients"
+msgstr ""
+
+#: lib/app.php:173
+msgid "Deliverer"
+msgstr ""
+
+#: lib/app.php:174
+msgid "Holidays"
+msgstr ""
+
+#: lib/app.php:175
+msgid "Ideas"
+msgstr ""
+
+#: lib/app.php:176
+msgid "Journey"
+msgstr ""
+
+#: lib/app.php:177
+msgid "Jubilee"
+msgstr ""
+
+#: lib/app.php:178
+msgid "Meeting"
+msgstr ""
+
+#: lib/app.php:179
+msgid "Other"
+msgstr ""
+
+#: lib/app.php:180
+msgid "Personal"
+msgstr ""
+
+#: lib/app.php:181
+msgid "Projects"
+msgstr ""
+
+#: lib/app.php:182
+msgid "Questions"
+msgstr ""
+
+#: lib/hooks.php:102
+msgid "{name}'s Birthday"
+msgstr ""
+
+#: templates/index.php:15
+msgid "Add Contact"
+msgstr "Thêm liên lạc"
+
+#: templates/index.php:16 templates/index.php:18 templates/part.import.php:17
+msgid "Import"
+msgstr ""
+
+#: templates/index.php:20
+msgid "Addressbooks"
+msgstr "Sổ địa chỉ"
+
+#: templates/index.php:37 templates/part.import.php:24
+msgid "Close"
+msgstr ""
+
+#: templates/index.php:39
+msgid "Keyboard shortcuts"
+msgstr ""
+
+#: templates/index.php:41
+msgid "Navigation"
+msgstr ""
+
+#: templates/index.php:44
+msgid "Next contact in list"
+msgstr ""
+
+#: templates/index.php:46
+msgid "Previous contact in list"
+msgstr ""
+
+#: templates/index.php:48
+msgid "Expand/collapse current addressbook"
+msgstr ""
+
+#: templates/index.php:50
+msgid "Next/previous addressbook"
+msgstr ""
+
+#: templates/index.php:54
+msgid "Actions"
+msgstr ""
+
+#: templates/index.php:57
+msgid "Refresh contacts list"
+msgstr ""
+
+#: templates/index.php:59
+msgid "Add new contact"
+msgstr ""
+
+#: templates/index.php:61
+msgid "Add new addressbook"
+msgstr ""
+
+#: templates/index.php:63
+msgid "Delete current contact"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:1
+msgid "Configure Address Books"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:16
+msgid "New Address Book"
+msgstr ""
+
+#: templates/part.chooseaddressbook.php:21
+#: templates/part.chooseaddressbook.rowfields.php:8
+msgid "CardDav Link"
+msgstr "CardDav Link"
+
+#: templates/part.chooseaddressbook.rowfields.php:11
+msgid "Download"
+msgstr "Tải về"
+
+#: templates/part.chooseaddressbook.rowfields.php:14
+msgid "Edit"
+msgstr "Sửa"
+
+#: templates/part.chooseaddressbook.rowfields.php:17
+#: templates/part.contact.php:39 templates/part.contact.php:41
+#: templates/part.contact.php:43 templates/part.contact.php:45
+#: templates/part.contact.php:49
+msgid "Delete"
+msgstr "Xóa"
+
+#: templates/part.contact.php:16
+msgid "Drop photo to upload"
+msgstr ""
+
+#: templates/part.contact.php:18
+msgid "Delete current photo"
+msgstr ""
+
+#: templates/part.contact.php:19
+msgid "Edit current photo"
+msgstr ""
+
+#: templates/part.contact.php:20
+msgid "Upload new photo"
+msgstr ""
+
+#: templates/part.contact.php:21
+msgid "Select photo from ownCloud"
+msgstr ""
+
+#: templates/part.contact.php:34
+msgid "Format custom, Short name, Full name, Reverse or Reverse with comma"
+msgstr ""
+
+#: templates/part.contact.php:35
+msgid "Edit name details"
+msgstr ""
+
+#: templates/part.contact.php:40 templates/part.contact.php:112
+msgid "Nickname"
+msgstr ""
+
+#: templates/part.contact.php:41
+msgid "Enter nickname"
+msgstr ""
+
+#: templates/part.contact.php:42 templates/part.contact.php:118
+msgid "Web site"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "http://www.somesite.com"
+msgstr ""
+
+#: templates/part.contact.php:43
+msgid "Go to web site"
+msgstr ""
+
+#: templates/part.contact.php:45
+msgid "dd-mm-yyyy"
+msgstr ""
+
+#: templates/part.contact.php:46 templates/part.contact.php:119
+msgid "Groups"
+msgstr ""
+
+#: templates/part.contact.php:48
+msgid "Separate groups with commas"
+msgstr ""
+
+#: templates/part.contact.php:49
+msgid "Edit groups"
+msgstr ""
+
+#: templates/part.contact.php:62 templates/part.contact.php:76
+msgid "Preferred"
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Please specify a valid email address."
+msgstr ""
+
+#: templates/part.contact.php:63
+msgid "Enter email address"
+msgstr ""
+
+#: templates/part.contact.php:67
+msgid "Mail to address"
+msgstr ""
+
+#: templates/part.contact.php:68
+msgid "Delete email address"
+msgstr ""
+
+#: templates/part.contact.php:77
+msgid "Enter phone number"
+msgstr ""
+
+#: templates/part.contact.php:81
+msgid "Delete phone number"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "View on map"
+msgstr ""
+
+#: templates/part.contact.php:91
+msgid "Edit address details"
+msgstr ""
+
+#: templates/part.contact.php:102
+msgid "Add notes here."
+msgstr ""
+
+#: templates/part.contact.php:109
+msgid "Add field"
+msgstr ""
+
+#: templates/part.contact.php:114
+msgid "Phone"
+msgstr "Điện thoại"
+
+#: templates/part.contact.php:117
+msgid "Note"
+msgstr ""
+
+#: templates/part.contact.php:122
+msgid "Download contact"
+msgstr ""
+
+#: templates/part.contact.php:123
+msgid "Delete contact"
+msgstr "Xóa liên lạc"
+
+#: templates/part.cropphoto.php:65
+msgid "The temporary image has been removed from cache."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:6
+msgid "Edit address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:10
+msgid "Type"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:18
+#: templates/part.edit_address_dialog.php:21
+msgid "PO Box"
+msgstr "Hòm thư bưu điện"
+
+#: templates/part.edit_address_dialog.php:24
+msgid "Street address"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:27
+msgid "Street and number"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:30
+msgid "Extended"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:33
+msgid "Apartment number etc."
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:36
+#: templates/part.edit_address_dialog.php:39
+msgid "City"
+msgstr "Thành phố"
+
+#: templates/part.edit_address_dialog.php:42
+msgid "Region"
+msgstr "Vùng/miền"
+
+#: templates/part.edit_address_dialog.php:45
+msgid "E.g. state or province"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:48
+msgid "Zipcode"
+msgstr "Mã bưu điện"
+
+#: templates/part.edit_address_dialog.php:51
+msgid "Postal code"
+msgstr ""
+
+#: templates/part.edit_address_dialog.php:54
+#: templates/part.edit_address_dialog.php:57
+msgid "Country"
+msgstr "Quốc gia"
+
+#: templates/part.edit_name_dialog.php:16
+msgid "Addressbook"
+msgstr "Sổ địa chỉ"
+
+#: templates/part.edit_name_dialog.php:23
+msgid "Hon. prefixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:27
+msgid "Miss"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:28
+msgid "Ms"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:29
+msgid "Mr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:30
+msgid "Sir"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:31
+msgid "Mrs"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:32
+msgid "Dr"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:35
+msgid "Given name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:37
+msgid "Additional names"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:39
+msgid "Family name"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:41
+msgid "Hon. suffixes"
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:45
+msgid "J.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:46
+msgid "M.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:47
+msgid "D.O."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:48
+msgid "D.C."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:49
+msgid "Ph.D."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:50
+msgid "Esq."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:51
+msgid "Jr."
+msgstr ""
+
+#: templates/part.edit_name_dialog.php:52
+msgid "Sn."
+msgstr ""
+
+#: templates/part.editaddressbook.php:9
+msgid "New Addressbook"
+msgstr "Sổ địa chỉ mới"
+
+#: templates/part.editaddressbook.php:9
+msgid "Edit Addressbook"
+msgstr "Sửa sổ địa chỉ"
+
+#: templates/part.editaddressbook.php:12
+msgid "Displayname"
+msgstr "Hiển thị tên"
+
+#: templates/part.editaddressbook.php:23
+msgid "Active"
+msgstr "Kích hoạt"
+
+#: templates/part.editaddressbook.php:29
+msgid "Save"
+msgstr "Lưu"
+
+#: templates/part.editaddressbook.php:29
+msgid "Submit"
+msgstr "Submit"
+
+#: templates/part.editaddressbook.php:30
+msgid "Cancel"
+msgstr "Hủy"
+
+#: templates/part.import.php:1
+msgid "Import a contacts file"
+msgstr ""
+
+#: templates/part.import.php:6
+msgid "Please choose the addressbook"
+msgstr ""
+
+#: templates/part.import.php:10
+msgid "create a new addressbook"
+msgstr ""
+
+#: templates/part.import.php:15
+msgid "Name of new addressbook"
+msgstr ""
+
+#: templates/part.import.php:20
+msgid "Importing contacts"
+msgstr ""
+
+#: templates/part.no_contacts.php:2
+msgid "You have no contacts in your addressbook."
+msgstr ""
+
+#: templates/part.no_contacts.php:4
+msgid "Add contact"
+msgstr ""
+
+#: templates/part.no_contacts.php:5
+msgid "Configure addressbooks"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:1
+msgid "Select Address Books"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:20
+msgid "Enter name"
+msgstr ""
+
+#: templates/part.selectaddressbook.php:22
+msgid "Enter description"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "CardDAV syncing addresses"
+msgstr ""
+
+#: templates/settings.php:4
+msgid "more info"
+msgstr ""
+
+#: templates/settings.php:6
+msgid "Primary address (Kontact et al)"
+msgstr ""
+
+#: templates/settings.php:8
+msgid "iOS/OS X"
+msgstr ""
+
+#: templates/settings.php:10
+msgid "Read only vCard directory link(s)"
+msgstr ""
diff --git a/l10n/vi/core.po b/l10n/vi/core.po
new file mode 100644
index 00000000000..b00d5071671
--- /dev/null
+++ b/l10n/vi/core.po
@@ -0,0 +1,269 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Son Nguyen <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:28+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/vcategories/add.php:23 ajax/vcategories/delete.php:23
+msgid "Application name not provided."
+msgstr "Tên ứng dụng không tồn tại"
+
+#: ajax/vcategories/add.php:29
+msgid "No category to add?"
+msgstr "Không có danh mục được thêm?"
+
+#: ajax/vcategories/add.php:36
+msgid "This category already exists: "
+msgstr "Danh mục này đã được tạo :"
+
+#: js/jquery-ui-1.8.16.custom.min.js:511
+msgid "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
+msgstr "ui-datepicker-group';if(i[1]>1)switch(G){case 0:y+="
+
+#: js/js.js:519
+msgid "January"
+msgstr "Tháng 1"
+
+#: js/js.js:519
+msgid "February"
+msgstr "Tháng 2"
+
+#: js/js.js:519
+msgid "March"
+msgstr "Tháng 3"
+
+#: js/js.js:519
+msgid "April"
+msgstr "Tháng 4"
+
+#: js/js.js:519
+msgid "May"
+msgstr "Tháng 5"
+
+#: js/js.js:519
+msgid "June"
+msgstr "Tháng 6"
+
+#: js/js.js:520
+msgid "July"
+msgstr "Tháng 7"
+
+#: js/js.js:520
+msgid "August"
+msgstr "Tháng 8"
+
+#: js/js.js:520
+msgid "September"
+msgstr "Tháng 9"
+
+#: js/js.js:520
+msgid "October"
+msgstr "Tháng 10"
+
+#: js/js.js:520
+msgid "November"
+msgstr "Tháng 11"
+
+#: js/js.js:520
+msgid "December"
+msgstr "Tháng 12"
+
+#: js/oc-dialogs.js:143 js/oc-dialogs.js:163
+msgid "Cancel"
+msgstr "Hủy"
+
+#: js/oc-dialogs.js:159
+msgid "No"
+msgstr "No"
+
+#: js/oc-dialogs.js:160
+msgid "Yes"
+msgstr "Yes"
+
+#: js/oc-dialogs.js:177
+msgid "Ok"
+msgstr "Ok"
+
+#: js/oc-vcategories.js:68
+msgid "No categories selected for deletion."
+msgstr "Không có thể loại nào được chọn để xóa."
+
+#: js/oc-vcategories.js:68
+msgid "Error"
+msgstr "Lỗi"
+
+#: lostpassword/index.php:26
+msgid "ownCloud password reset"
+msgstr "Khôi phục mật khẩu Owncloud "
+
+#: lostpassword/templates/email.php:1
+msgid "Use the following link to reset your password: {link}"
+msgstr "Dùng đường dẫn sau để khôi phục lại mật khẩu : {link}"
+
+#: lostpassword/templates/lostpassword.php:3
+msgid "You will receive a link to reset your password via Email."
+msgstr "Vui lòng kiểm tra Email để khôi phục lại mật khẩu."
+
+#: lostpassword/templates/lostpassword.php:5
+msgid "Requested"
+msgstr "Yêu cầu"
+
+#: lostpassword/templates/lostpassword.php:8
+msgid "Login failed!"
+msgstr "Bạn đã nhập sai mật khẩu hay tên người dùng !"
+
+#: lostpassword/templates/lostpassword.php:11 templates/installation.php:25
+#: templates/login.php:9
+msgid "Username"
+msgstr "Tên người dùng"
+
+#: lostpassword/templates/lostpassword.php:15
+msgid "Request reset"
+msgstr "Yêu cầu thiết lập lại "
+
+#: lostpassword/templates/resetpassword.php:4
+msgid "Your password was reset"
+msgstr "Mật khẩu của bạn đã được khôi phục"
+
+#: lostpassword/templates/resetpassword.php:5
+msgid "To login page"
+msgstr "Trang đăng nhập"
+
+#: lostpassword/templates/resetpassword.php:8
+msgid "New password"
+msgstr "Mật khẩu mới"
+
+#: lostpassword/templates/resetpassword.php:11
+msgid "Reset password"
+msgstr "Khôi phục mật khẩu"
+
+#: strings.php:5
+msgid "Personal"
+msgstr "Cá nhân"
+
+#: strings.php:6
+msgid "Users"
+msgstr "Người sử dụng"
+
+#: strings.php:7
+msgid "Apps"
+msgstr "Ứng dụng"
+
+#: strings.php:8
+msgid "Admin"
+msgstr "Quản trị"
+
+#: strings.php:9
+msgid "Help"
+msgstr "Giúp đỡ"
+
+#: templates/403.php:12
+msgid "Access forbidden"
+msgstr "Truy cập bị cấm "
+
+#: templates/404.php:12
+msgid "Cloud not found"
+msgstr "Không tìm thấy Clound"
+
+#: templates/edit_categories_dialog.php:4
+msgid "Edit categories"
+msgstr "Sửa thể loại"
+
+#: templates/edit_categories_dialog.php:14
+msgid "Add"
+msgstr "Thêm"
+
+#: templates/installation.php:23
+msgid "Create an <strong>admin account</strong>"
+msgstr "Tạo một <strong>tài khoản quản trị</strong>"
+
+#: templates/installation.php:29 templates/login.php:13
+msgid "Password"
+msgstr "Mật khẩu"
+
+#: templates/installation.php:35
+msgid "Advanced"
+msgstr "Nâng cao"
+
+#: templates/installation.php:37
+msgid "Data folder"
+msgstr "Thư mục dữ liệu"
+
+#: templates/installation.php:44
+msgid "Configure the database"
+msgstr "Cấu hình Cơ Sở Dữ Liệu"
+
+#: templates/installation.php:49 templates/installation.php:60
+#: templates/installation.php:70
+msgid "will be used"
+msgstr "được sử dụng"
+
+#: templates/installation.php:82
+msgid "Database user"
+msgstr "Người dùng cơ sở dữ liệu"
+
+#: templates/installation.php:86
+msgid "Database password"
+msgstr "Mật khẩu cơ sở dữ liệu"
+
+#: templates/installation.php:90
+msgid "Database name"
+msgstr "Tên cơ sở dữ liệu"
+
+#: templates/installation.php:96
+msgid "Database host"
+msgstr "Database host"
+
+#: templates/installation.php:101
+msgid "Finish setup"
+msgstr "Cài đặt hoàn tất"
+
+#: templates/layout.guest.php:42
+msgid "web services under your control"
+msgstr "các dịch vụ web dưới sự kiểm soát của bạn"
+
+#: templates/layout.user.php:49
+msgid "Log out"
+msgstr "Đăng xuất"
+
+#: templates/layout.user.php:64 templates/layout.user.php:65
+msgid "Settings"
+msgstr "Cài đặt"
+
+#: templates/login.php:6
+msgid "Lost your password?"
+msgstr "Bạn quên mật khẩu ?"
+
+#: templates/login.php:17
+msgid "remember"
+msgstr "Nhớ"
+
+#: templates/login.php:18
+msgid "Log in"
+msgstr "Đăng nhập"
+
+#: templates/logout.php:1
+msgid "You are logged out."
+msgstr "Bạn đã đăng xuất."
+
+#: templates/part.pagenavi.php:3
+msgid "prev"
+msgstr "Lùi lại"
+
+#: templates/part.pagenavi.php:20
+msgid "next"
+msgstr "Kế tiếp"
diff --git a/l10n/vi/files.po b/l10n/vi/files.po
new file mode 100644
index 00000000000..c7b868c5bc7
--- /dev/null
+++ b/l10n/vi/files.po
@@ -0,0 +1,199 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:29+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/upload.php:20
+msgid "There is no error, the file uploaded with success"
+msgstr ""
+
+#: ajax/upload.php:21
+msgid "The uploaded file exceeds the upload_max_filesize directive in php.ini"
+msgstr ""
+
+#: ajax/upload.php:22
+msgid ""
+"The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in "
+"the HTML form"
+msgstr ""
+
+#: ajax/upload.php:23
+msgid "The uploaded file was only partially uploaded"
+msgstr ""
+
+#: ajax/upload.php:24
+msgid "No file was uploaded"
+msgstr ""
+
+#: ajax/upload.php:25
+msgid "Missing a temporary folder"
+msgstr ""
+
+#: ajax/upload.php:26
+msgid "Failed to write to disk"
+msgstr ""
+
+#: appinfo/app.php:6
+msgid "Files"
+msgstr "Tập tin"
+
+#: js/fileactions.js:95
+msgid "Unshare"
+msgstr ""
+
+#: js/fileactions.js:97 templates/index.php:56
+msgid "Delete"
+msgstr "Xóa"
+
+#: js/filelist.js:186
+msgid "undo deletion"
+msgstr ""
+
+#: js/files.js:170
+msgid "generating ZIP-file, it may take some time."
+msgstr ""
+
+#: js/files.js:199
+msgid "Unable to upload your file as it is a directory or has 0 bytes"
+msgstr ""
+
+#: js/files.js:199
+msgid "Upload Error"
+msgstr "Tải lên lỗi"
+
+#: js/files.js:227 js/files.js:318 js/files.js:347
+msgid "Pending"
+msgstr "Chờ"
+
+#: js/files.js:332
+msgid "Upload cancelled."
+msgstr "Hủy tải lên"
+
+#: js/files.js:456
+msgid "Invalid name, '/' is not allowed."
+msgstr "Tên không hợp lệ ,không được phép dùng '/'"
+
+#: js/files.js:631 templates/index.php:55
+msgid "Size"
+msgstr "Kích cỡ"
+
+#: js/files.js:632 templates/index.php:56
+msgid "Modified"
+msgstr "Thay đổi"
+
+#: js/files.js:659
+msgid "folder"
+msgstr "folder"
+
+#: js/files.js:661
+msgid "folders"
+msgstr "folders"
+
+#: js/files.js:669
+msgid "file"
+msgstr "file"
+
+#: js/files.js:671
+msgid "files"
+msgstr "files"
+
+#: templates/admin.php:5
+msgid "File handling"
+msgstr "Xử lý tập tin"
+
+#: templates/admin.php:7
+msgid "Maximum upload size"
+msgstr "Kích thước tối đa "
+
+#: templates/admin.php:7
+msgid "max. possible: "
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Needed for multi-file and folder downloads."
+msgstr ""
+
+#: templates/admin.php:9
+msgid "Enable ZIP-download"
+msgstr "Cho phép ZIP-download"
+
+#: templates/admin.php:11
+msgid "0 is unlimited"
+msgstr "0 là không giới hạn"
+
+#: templates/admin.php:12
+msgid "Maximum input size for ZIP files"
+msgstr "Kích thước tối đa cho các tập tin ZIP"
+
+#: templates/index.php:7
+msgid "New"
+msgstr "Mới"
+
+#: templates/index.php:9
+msgid "Text file"
+msgstr "Tập tin văn bản"
+
+#: templates/index.php:10
+msgid "Folder"
+msgstr "Folder"
+
+#: templates/index.php:11
+msgid "From url"
+msgstr "Từ url"
+
+#: templates/index.php:21
+msgid "Upload"
+msgstr "Tải lên"
+
+#: templates/index.php:27
+msgid "Cancel upload"
+msgstr "Hủy upload"
+
+#: templates/index.php:39
+msgid "Nothing in here. Upload something!"
+msgstr "Không có gì ở đây .Hãy tải lên một cái gì đó !"
+
+#: templates/index.php:47
+msgid "Name"
+msgstr "Tên"
+
+#: templates/index.php:49
+msgid "Share"
+msgstr "Chia sẻ"
+
+#: templates/index.php:51
+msgid "Download"
+msgstr "Tải xuống"
+
+#: templates/index.php:64
+msgid "Upload too large"
+msgstr "File tải lên quá lớn"
+
+#: templates/index.php:66
+msgid ""
+"The files you are trying to upload exceed the maximum size for file uploads "
+"on this server."
+msgstr ""
+
+#: templates/index.php:71
+msgid "Files are being scanned, please wait."
+msgstr "Tập tin đang được quét ,vui lòng chờ."
+
+#: templates/index.php:74
+msgid "Current scanning"
+msgstr ""
diff --git a/l10n/vi/gallery.po b/l10n/vi/gallery.po
new file mode 100644
index 00000000000..741f026c53d
--- /dev/null
+++ b/l10n/vi/gallery.po
@@ -0,0 +1,60 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Son Nguyen <sonnghit@gmail.com>, 2012.
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: appinfo/app.php:39
+msgid "Pictures"
+msgstr "Hình ảnh"
+
+#: js/pictures.js:12
+msgid "Share gallery"
+msgstr "Chia sẻ gallery"
+
+#: js/pictures.js:32
+msgid "Error: "
+msgstr "Lỗi :"
+
+#: js/pictures.js:32
+msgid "Internal error"
+msgstr "Lỗi nội bộ"
+
+#: templates/index.php:27
+msgid "Slideshow"
+msgstr ""
+
+#: templates/view_album.php:19
+msgid "Back"
+msgstr "Trở lại"
+
+#: templates/view_album.php:36
+msgid "Remove confirmation"
+msgstr "Xóa xác nhận"
+
+#: templates/view_album.php:37
+msgid "Do you want to remove album"
+msgstr "Bạn muốn xóa album này "
+
+#: templates/view_album.php:40
+msgid "Change album name"
+msgstr "Đổi tên album"
+
+#: templates/view_album.php:43
+msgid "New album name"
+msgstr "Tên album mới"
diff --git a/l10n/vi/media.po b/l10n/vi/media.po
new file mode 100644
index 00000000000..9c4613fa2bc
--- /dev/null
+++ b/l10n/vi/media.po
@@ -0,0 +1,67 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-23 06:41+0000\n"
+"Last-Translator: Sơn Nguyễn <sonnghit@gmail.com>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: appinfo/app.php:45 templates/player.php:8
+msgid "Music"
+msgstr "Âm nhạc"
+
+#: js/music.js:18
+msgid "Add album to playlist"
+msgstr "Thêm album vào playlist"
+
+#: templates/music.php:3 templates/player.php:12
+msgid "Play"
+msgstr "Play"
+
+#: templates/music.php:4 templates/music.php:26 templates/player.php:13
+msgid "Pause"
+msgstr "Tạm dừng"
+
+#: templates/music.php:5
+msgid "Previous"
+msgstr "Trang trước"
+
+#: templates/music.php:6 templates/player.php:14
+msgid "Next"
+msgstr "Tiếp theo"
+
+#: templates/music.php:7
+msgid "Mute"
+msgstr "Tắt"
+
+#: templates/music.php:8
+msgid "Unmute"
+msgstr "Bật"
+
+#: templates/music.php:25
+msgid "Rescan Collection"
+msgstr "Quét lại bộ sưu tập"
+
+#: templates/music.php:37
+msgid "Artist"
+msgstr "Nghệ sỹ"
+
+#: templates/music.php:38
+msgid "Album"
+msgstr "Album"
+
+#: templates/music.php:39
+msgid "Title"
+msgstr "Tiêu đề"
diff --git a/l10n/vi/settings.po b/l10n/vi/settings.po
new file mode 100644
index 00000000000..e387aaaa9e1
--- /dev/null
+++ b/l10n/vi/settings.po
@@ -0,0 +1,208 @@
+# SOME DESCRIPTIVE TITLE.
+# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
+# This file is distributed under the same license as the PACKAGE package.
+#
+# Translators:
+# Son Nguyen <sonnghit@gmail.com>, 2012.
+# Sơn Nguyễn <sonnghit@gmail.com>, 2012.
+msgid ""
+msgstr ""
+"Project-Id-Version: ownCloud\n"
+"Report-Msgid-Bugs-To: http://bugs.owncloud.org/\n"
+"POT-Creation-Date: 2012-07-26 08:03+0200\n"
+"PO-Revision-Date: 2012-07-25 19:30+0000\n"
+"Last-Translator: owncloud_robot <thomas.mueller@tmit.eu>\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/owncloud/language/vi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: vi\n"
+"Plural-Forms: nplurals=1; plural=0\n"
+
+#: ajax/lostpassword.php:14
+msgid "Email saved"
+msgstr "Lưu email"
+
+#: ajax/lostpassword.php:16
+msgid "Invalid email"
+msgstr "Email không hợp lệ"
+
+#: ajax/openid.php:16
+msgid "OpenID Changed"
+msgstr "Đổi OpenID"
+
+#: ajax/openid.php:18 ajax/setlanguage.php:20 ajax/setlanguage.php:23
+msgid "Invalid request"
+msgstr "Yêu cầu không hợp lệ"
+
+#: ajax/setlanguage.php:18
+msgid "Language changed"
+msgstr "Ngôn ngữ đã được thay đổi"
+
+#: js/apps.js:31 js/apps.js:67
+msgid "Disable"
+msgstr "Vô hiệu"
+
+#: js/apps.js:31 js/apps.js:54
+msgid "Enable"
+msgstr "Cho phép"
+
+#: js/personal.js:69
+msgid "Saving..."
+msgstr "Đang tiến hành lưu ..."
+
+#: personal.php:41 personal.php:42
+msgid "__language_name__"
+msgstr "__Ngôn ngữ___"
+
+#: templates/admin.php:14
+msgid "Security Warning"
+msgstr ""
+
+#: templates/admin.php:28
+msgid "Log"
+msgstr "Log"
+
+#: templates/admin.php:55
+msgid "More"
+msgstr "nhiều hơn"
+
+#: templates/apps.php:10
+msgid "Add your App"
+msgstr "Thêm ứng dụng của bạn"
+
+#: templates/apps.php:24
+msgid "Select an App"
+msgstr "Chọn một ứng dụng"
+
+#: templates/apps.php:27
+msgid "See application page at apps.owncloud.com"
+msgstr "Xem ứng dụng tại apps.owncloud.com"
+
+#: templates/apps.php:28
+msgid "-licensed"
+msgstr "Giấy phép đã được cấp"
+
+#: templates/apps.php:28
+msgid "by"
+msgstr "bởi"
+
+#: templates/help.php:8
+msgid "Documentation"
+msgstr "Tài liệu"
+
+#: templates/help.php:9
+msgid "Managing Big Files"
+msgstr "Quản lý tập tin lớn"
+
+#: templates/help.php:10
+msgid "Ask a question"
+msgstr "Đặt câu hỏi"
+
+#: templates/help.php:22
+msgid "Problems connecting to help database."
+msgstr "Vấn đề kết nối đến cơ sở dữ liệu."
+
+#: templates/help.php:23
+msgid "Go there manually."
+msgstr "Đến bằng thủ công"
+
+#: templates/help.php:31
+msgid "Answer"
+msgstr "trả lời"
+
+#: templates/personal.php:8
+msgid "You use"
+msgstr "Bạn sử dụng"
+
+#: templates/personal.php:8
+msgid "of the available"
+msgstr "có sẵn"
+
+#: templates/personal.php:12
+msgid "Desktop and Mobile Syncing Clients"
+msgstr "Đồng bộ dữ liệu"
+
+#: templates/personal.php:13
+msgid "Download"
+msgstr "Tải về"
+
+#: templates/personal.php:19
+msgid "Your password got changed"
+msgstr "Mật khẩu đã được thay đổi"
+
+#: templates/personal.php:20
+msgid "Unable to change your password"
+msgstr "Không thể đổi mật khẩu"
+
+#: templates/personal.php:21
+msgid "Current password"
+msgstr "Mật khẩu cũ"
+
+#: templates/personal.php:22
+msgid "New password"
+msgstr "Mật khẩu mới "
+
+#: templates/personal.php:23
+msgid "show"
+msgstr "Hiện"
+
+#: templates/personal.php:24
+msgid "Change password"
+msgstr "Đổi mật khẩu"
+
+#: templates/personal.php:30
+msgid "Email"
+msgstr "Email"
+
+#: templates/personal.php:31
+msgid "Your email address"
+msgstr "Email của bạn"
+
+#: templates/personal.php:32
+msgid "Fill in an email address to enable password recovery"
+msgstr "Nhập địa chỉ email của bạn để khôi phục lại mật khẩu"
+
+#: templates/personal.php:38 templates/personal.php:39
+msgid "Language"
+msgstr "Ngôn ngữ"
+
+#: templates/personal.php:44
+msgid "Help translate"
+msgstr "Dịch "
+
+#: templates/personal.php:51
+msgid "use this address to connect to your ownCloud in your file manager"
+msgstr "sử dụng địa chỉ này để kết nối với ownCloud của bạn trong quản lý tập tin "
+
+#: templates/users.php:15 templates/users.php:60
+msgid "Name"
+msgstr "Tên"
+
+#: templates/users.php:17 templates/users.php:61
+msgid "Password"
+msgstr "Mật khẩu"
+
+#: templates/users.php:19 templates/users.php:62 templates/users.php:78
+msgid "Groups"
+msgstr "Nhóm"
+
+#: templates/users.php:25
+msgid "Create"
+msgstr "Tạo"
+
+#: templates/users.php:28
+msgid "Default Quota"
+msgstr "Hạn ngạch mặt định"
+
+#: templates/users.php:47 templates/users.php:103
+msgid "Other"
+msgstr "Khác"
+
+#: templates/users.php:63
+msgid "Quota"
+msgstr "Hạn ngạch"
+
+#: templates/users.php:110
+msgid "Delete"
+msgstr "Xóa"
diff --git a/lib/app.php b/lib/app.php
index d6b2904f3c2..d1018c37aa7 100755
--- a/lib/app.php
+++ b/lib/app.php
@@ -195,7 +195,7 @@ class OC_App{
// check if the app is compatible with this version of ownCloud
$info=OC_App::getAppInfo($app);
$version=OC_Util::getVersion();
- if(!isset($info['require']) or ($version[0]>$info['require'])){
+ if(!isset($info['require']) or ($version[0]>$info['require'])){
OC_Log::write('core','App "'.$info['name'].'" can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
return false;
}else{
@@ -336,8 +336,8 @@ class OC_App{
}
/**
- * Get the path where to install apps
- */
+ * Get the path where to install apps
+ */
public static function getInstallPath() {
if(OC_Config::getValue('appstoreenabled', true)==false) {
return false;
diff --git a/lib/base.php b/lib/base.php
index 631ed4fcce6..888dc265d64 100644
--- a/lib/base.php
+++ b/lib/base.php
@@ -83,6 +83,9 @@ class OC{
elseif(strpos($className,'OCP\\')===0){
require_once 'public/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
}
+ elseif(strpos($className,'OCA\\')===0){
+ require_once 'apps/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php');
+ }
elseif(strpos($className,'Sabre_')===0) {
require_once str_replace('_','/',$className) . '.php';
}
diff --git a/lib/cache.php b/lib/cache.php
index 1f269174fad..55f189a5da8 100644
--- a/lib/cache.php
+++ b/lib/cache.php
@@ -7,48 +7,96 @@
*/
class OC_Cache {
+ /**
+ * @var OC_Cache $user_cache
+ */
static protected $user_cache;
+ /**
+ * @var OC_Cache $global_cache
+ */
static protected $global_cache;
+ /**
+ * @var OC_Cache $global_cache_fast
+ */
+ static protected $global_cache_fast;
+ /**
+ * @var OC_Cache $user_cache_fast
+ */
+ static protected $user_cache_fast;
+ static protected $isFast=null;
- static public function getGlobalCache() {
+ /**
+ * get the global cache
+ * @return OC_Cache
+ */
+ static public function getGlobalCache($fast=false) {
if (!self::$global_cache) {
- $fast_cache = null;
- if (!$fast_cache && function_exists('xcache_set')) {
- $fast_cache = new OC_Cache_XCache(true);
+ self::$global_cache_fast = null;
+ if (!self::$global_cache_fast && function_exists('xcache_set')) {
+ self::$global_cache_fast = new OC_Cache_XCache(true);
}
- if (!$fast_cache && function_exists('apc_store')) {
- $fast_cache = new OC_Cache_APC(true);
+ if (!self::$global_cache_fast && function_exists('apc_store')) {
+ self::$global_cache_fast = new OC_Cache_APC(true);
}
+
self::$global_cache = new OC_Cache_FileGlobal();
- if ($fast_cache) {
- self::$global_cache = new OC_Cache_Broker($fast_cache, self::$global_cache);
+ if (self::$global_cache_fast) {
+ self::$global_cache = new OC_Cache_Broker(self::$global_cache_fast, self::$global_cache);
+ }
+ }
+ if($fast){
+ if(self::$global_cache_fast){
+ return self::$global_cache_fast;
+ }else{
+ return false;
}
}
return self::$global_cache;
}
- static public function getUserCache() {
+ /**
+ * get the user cache
+ * @return OC_Cache
+ */
+ static public function getUserCache($fast=false) {
if (!self::$user_cache) {
- $fast_cache = null;
- if (!$fast_cache && function_exists('xcache_set')) {
- $fast_cache = new OC_Cache_XCache();
+ self::$user_cache_fast = null;
+ if (!self::$user_cache_fast && function_exists('xcache_set')) {
+ self::$user_cache_fast = new OC_Cache_XCache();
}
- if (!$fast_cache && function_exists('apc_store')) {
- $fast_cache = new OC_Cache_APC();
+ if (!self::$user_cache_fast && function_exists('apc_store')) {
+ self::$user_cache_fast = new OC_Cache_APC();
}
+
self::$user_cache = new OC_Cache_File();
- if ($fast_cache) {
- self::$user_cache = new OC_Cache_Broker($fast_cache, self::$user_cache);
+ if (self::$user_cache_fast) {
+ self::$user_cache = new OC_Cache_Broker(self::$user_cache_fast, self::$user_cache);
+ }
+ }
+
+ if($fast){
+ if(self::$user_cache_fast){
+ return self::$user_cache_fast;
+ }else{
+ return false;
}
}
return self::$user_cache;
}
+ /**
+ * get a value from the user cache
+ * @return mixed
+ */
static public function get($key) {
$user_cache = self::getUserCache();
return $user_cache->get($key);
}
+ /**
+ * set a value in the user cache
+ * @return bool
+ */
static public function set($key, $value, $ttl=0) {
if (empty($key)) {
return false;
@@ -57,19 +105,43 @@ class OC_Cache {
return $user_cache->set($key, $value, $ttl);
}
+ /**
+ * check if a value is set in the user cache
+ * @return bool
+ */
static public function hasKey($key) {
$user_cache = self::getUserCache();
return $user_cache->hasKey($key);
}
+ /**
+ * remove an item from the user cache
+ * @return bool
+ */
static public function remove($key) {
$user_cache = self::getUserCache();
return $user_cache->remove($key);
}
- static public function clear() {
+ /**
+ * clear the user cache of all entries starting with a prefix
+ * @param string prefix (optional)
+ * @return bool
+ */
+ static public function clear($prefix='') {
$user_cache = self::getUserCache();
- return $user_cache->clear();
+ return $user_cache->clear($prefix);
+ }
+
+ /**
+ * check if a fast memory based cache is available
+ * @return true
+ */
+ static public function isFast() {
+ if(is_null(self::$isFast)){
+ self::$isFast=function_exists('xcache_set') || function_exists('apc_store');
+ }
+ return self::$isFast;
}
}
diff --git a/lib/cache/apc.php b/lib/cache/apc.php
index 6cf47d0c158..c192fe2f196 100644
--- a/lib/cache/apc.php
+++ b/lib/cache/apc.php
@@ -43,14 +43,15 @@ class OC_Cache_APC {
return apc_delete($this->getNamespace().$key);
}
- public function clear(){
- $ns = $this->getNamespace();
+ public function clear($prefix=''){
+ $ns = $this->getNamespace().$prefix;
$cache = apc_cache_info('user');
foreach($cache['cache_list'] as $entry) {
if (strpos($entry['info'], $ns) === 0) {
apc_delete($entry['info']);
}
}
+ return true;
}
}
if(!function_exists('apc_exists')) {
diff --git a/lib/cache/broker.php b/lib/cache/broker.php
index 931d0dd407e..c2aceabaf53 100644
--- a/lib/cache/broker.php
+++ b/lib/cache/broker.php
@@ -46,8 +46,8 @@ class OC_Cache_Broker {
return $this->slow_cache->remove($key);
}
- public function clear(){
- $this->fast_cache->clear();
- $this->slow_cache->clear();
+ public function clear($prefix=''){
+ $this->fast_cache->clear($prefix);
+ $this->slow_cache->clear($prefix);
}
}
diff --git a/lib/cache/file.php b/lib/cache/file.php
index 0b7d3e30508..562c3d17167 100644
--- a/lib/cache/file.php
+++ b/lib/cache/file.php
@@ -62,15 +62,16 @@ class OC_Cache_File{
return $storage->unlink($key);
}
- public function clear(){
+ public function clear($prefix=''){
$storage = $this->getStorage();
if($storage and $storage->is_dir('/')){
$dh=$storage->opendir('/');
while($file=readdir($dh)){
- if($file!='.' and $file!='..'){
+ if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)){
$storage->unlink('/'.$file);
}
}
}
+ return true;
}
}
diff --git a/lib/cache/xcache.php b/lib/cache/xcache.php
index bd55cee8f6b..951f9b47545 100644
--- a/lib/cache/xcache.php
+++ b/lib/cache/xcache.php
@@ -43,7 +43,8 @@ class OC_Cache_XCache {
return xcache_unset($this->getNamespace().$key);
}
- public function clear(){
- return xcache_unset_by_prefix($this->getNamespace());
+ public function clear($prefix=''){
+ xcache_unset_by_prefix($this->getNamespace().$prefix);
+ return true;
}
}
diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php
index 0842fc4fc65..7f8434c7151 100644
--- a/lib/connector/sabre/directory.php
+++ b/lib/connector/sabre/directory.php
@@ -52,7 +52,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
$newPath = $this->path . '/' . $name;
OC_Filesystem::file_put_contents($newPath,$data);
- return OC_Connector_Sabre_Node::getETagPropertyForFile($newPath);
+ return OC_Connector_Sabre_Node::getETagPropertyForPath($newPath);
}
/**
@@ -170,5 +170,25 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa
}
+ /**
+ * Returns a list of properties for this nodes.;
+ *
+ * The properties list is a list of propertynames the client requested,
+ * encoded as xmlnamespace#tagName, for example:
+ * http://www.example.org/namespace#author
+ * If the array is empty, all properties should be returned
+ *
+ * @param array $properties
+ * @return void
+ */
+ public function getProperties($properties) {
+ $props = parent::getProperties($properties);
+ if (in_array(self::GETETAG_PROPERTYNAME, $properties)
+ && !isset($props[self::GETETAG_PROPERTYNAME])) {
+ $props[self::GETETAG_PROPERTYNAME] =
+ OC_Connector_Sabre_Node::getETagPropertyForPath($this->path);
+ }
+ return $props;
+ }
}
diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php
index 80f0a0ab4d8..9d571fceb0d 100644
--- a/lib/connector/sabre/file.php
+++ b/lib/connector/sabre/file.php
@@ -47,7 +47,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
OC_Filesystem::file_put_contents($this->path,$data);
- return OC_Connector_Sabre_Node::getETagPropertyForFile($this->path);
+ return OC_Connector_Sabre_Node::getETagPropertyForPath($this->path);
}
/**
@@ -98,7 +98,16 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D
if (isset($properties[self::GETETAG_PROPERTYNAME])) {
return $properties[self::GETETAG_PROPERTYNAME];
}
- return $this->getETagPropertyForFile($this->path);
+ return $this->getETagPropertyForPath($this->path);
+ }
+
+ /**
+ * Creates a ETag for this path.
+ * @param string $path Path of the file
+ * @return string|null Returns null if the ETag can not effectively be determined
+ */
+ static protected function createETag($path) {
+ return OC_Filesystem::hash('md5', $path);
}
/**
diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php
index 3cb5412f09f..22506f27cf6 100644
--- a/lib/connector/sabre/node.php
+++ b/lib/connector/sabre/node.php
@@ -142,6 +142,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
public function updateProperties($properties) {
$existing = $this->getProperties(array());
foreach($properties as $propertyName => $propertyValue) {
+ $propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name
// If it was null, we need to delete the property
if (is_null($propertyValue)) {
if(array_key_exists( $propertyName, $existing )){
@@ -203,12 +204,21 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
}
/**
+ * Creates a ETag for this path.
+ * @param string $path Path of the file
+ * @return string|null Returns null if the ETag can not effectively be determined
+ */
+ static protected function createETag($path) {
+ return uniqid('', true);
+ }
+
+ /**
* Returns the ETag surrounded by double-quotes for this path.
* @param string $path Path of the file
* @return string|null Returns null if the ETag can not effectively be determined
*/
- static public function getETagPropertyForFile($path) {
- $tag = OC_Filesystem::hash('md5', $path);
+ static public function getETagPropertyForPath($path) {
+ $tag = self::createETag($path);
if (empty($tag)) {
return null;
}
@@ -222,7 +232,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr
* Remove the ETag from the cache.
* @param string $path Path of the file
*/
- static public function removeETagPropertyForFile($path) {
+ static public function removeETagPropertyForPath($path) {
$query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' );
$query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME ));
}
diff --git a/lib/db.php b/lib/db.php
index 6f083d17cfb..6971fe4a583 100644
--- a/lib/db.php
+++ b/lib/db.php
@@ -368,9 +368,6 @@ class OC_DB {
if( $definition instanceof MDB2_Schema_Error ){
die( $definition->getMessage().': '.$definition->getUserInfo());
}
-// if(OC_Config::getValue('dbtype','sqlite')=='sqlite'){
-// $definition['overwrite']=true;//always overwrite for sqlite
-// }
$ret=self::$schema->createDatabase( $definition );
// Die in case something went wrong
@@ -527,8 +524,7 @@ class OC_DB {
* @brief replaces the owncloud tables with a new set
* @param $file string path to the MDB2 xml db export file
*/
- public static function replaceDB( $file ){
-
+ public static function replaceDB( $file ){
$apps = OC_App::getAllApps();
self::beginTransaction();
// Delete the old tables
diff --git a/lib/eventsource.php b/lib/eventsource.php
index 2a8c6b92902..95af2e471bc 100644
--- a/lib/eventsource.php
+++ b/lib/eventsource.php
@@ -42,6 +42,9 @@ class OC_EventSource{
}else{
header("Content-Type: text/event-stream");
}
+ if( !OC_Util::isCallRegistered()){
+ exit();
+ }
flush();
}
diff --git a/lib/filecache.php b/lib/filecache.php
index 4b1774925c3..22f7427ae42 100644
--- a/lib/filecache.php
+++ b/lib/filecache.php
@@ -98,6 +98,10 @@ class OC_FileCache{
if(OC_DB::isError($result)){
OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR);
}
+
+ if($cache=OC_Cache::getUserCache(true)){
+ $cache->remove('fileid/'.$path);//ensure we don't have -1 cached
+ }
}
/**
@@ -146,6 +150,11 @@ class OC_FileCache{
$query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?');
$query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath)));
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)){
+ $cache->set('fileid/'.$newPath,$cache->get('fileid/'.$oldPath));
+ $cache->remove('fileid/'.$oldPath);
+ }
+
$query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE path LIKE ?');
$oldLength=strlen($oldPath);
$updateQuery=OC_DB::prepare('UPDATE *PREFIX*fscache SET path=?, path_hash=? WHERE path_hash=?');
@@ -153,6 +162,11 @@ class OC_FileCache{
$old=$row['path'];
$new=$newPath.substr($old,$oldLength);
$updateQuery->execute(array($new,md5($new),md5($old)));
+
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)){
+ $cache->set('fileid/'.$new,$cache->get('fileid/'.$old));
+ $cache->remove('fileid/'.$old);
+ }
}
}
@@ -171,6 +185,8 @@ class OC_FileCache{
//delete everything inside the folder
$query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path LIKE ?');
$query->execute(array($root.$path.'/%'));
+
+ OC_Cache::remove('fileid/'.$root.$path);
}
/**
@@ -245,9 +261,14 @@ class OC_FileCache{
if($root===false){
$root=OC_Filesystem::getRoot();
}
+
+ $fullPath=$root.$path;
+ if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)){
+ return $cache->get('fileid/'.$fullPath);
+ }
$query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?');
- $result=$query->execute(array(md5($root.$path)));
+ $result=$query->execute(array(md5($fullPath)));
if(OC_DB::isError($result)){
OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR);
return -1;
@@ -255,10 +276,15 @@ class OC_FileCache{
$result=$result->fetchRow();
if(is_array($result)){
- return $result['id'];
+ $id=$result['id'];
}else{
- return -1;
+ $id=-1;
+ }
+ if($cache=OC_Cache::getUserCache(true)){
+ $cache->set('fileid/'.$fullPath,$id);
}
+
+ return $id;
}
/**
diff --git a/lib/filestorage.php b/lib/filestorage.php
index e786127d525..fd4ad36530e 100644
--- a/lib/filestorage.php
+++ b/lib/filestorage.php
@@ -45,7 +45,7 @@ abstract class OC_Filestorage{
abstract public function copy($path1,$path2);
abstract public function fopen($path,$mode);
abstract public function getMimeType($path);
- abstract public function hash($type,$path,$raw);
+ abstract public function hash($type,$path,$raw = false);
abstract public function free_space($path);
abstract public function search($query);
abstract public function touch($path, $mtime=null);
diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php
index fd389d3e2d7..c77df38e6b1 100644
--- a/lib/filestorage/common.php
+++ b/lib/filestorage/common.php
@@ -195,7 +195,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage {
unlink($tmpFile);
return $mime;
}
- public function hash($type,$path,$raw){
+ public function hash($type,$path,$raw = false){
$tmpFile=$this->getLocalFile();
$hash=hash($type,$tmpFile,$raw);
unlink($tmpFile);
diff --git a/lib/filesystem.php b/lib/filesystem.php
index ec30ffb8f4c..d88b30c2f68 100644
--- a/lib/filesystem.php
+++ b/lib/filesystem.php
@@ -53,99 +53,99 @@ class OC_Filesystem{
static private $defaultInstance;
- /**
- * classname which used for hooks handling
- * used as signalclass in OC_Hooks::emit()
- */
- const CLASSNAME = 'OC_Filesystem';
-
- /**
- * signalname emited before file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_rename = 'rename';
-
- /**
- * signal emited after file renaming
- * @param oldpath
- * @param newpath
- */
- const signal_post_rename = 'post_rename';
-
- /**
- * signal emited before file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_create = 'create';
-
- /**
- * signal emited after file/dir creation
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_post_create = 'post_create';
-
- /**
- * signal emits before file/dir copy
- * @param oldpath
- * @param newpath
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_copy = 'copy';
-
- /**
- * signal emits after file/dir copy
- * @param oldpath
- * @param newpath
- */
- const signal_post_copy = 'post_copy';
-
- /**
- * signal emits before file/dir save
- * @param path
- * @param run changing this flag to false in hook handler will cancel event
- */
- const signal_write = 'write';
-
- /**
- * signal emits after file/dir save
- * @param path
- */
- const signal_post_write = 'post_write';
-
- /**
- * signal emits when reading file/dir
- * @param path
- */
- const signal_read = 'read';
-
- /**
- * signal emits when removing file/dir
- * @param path
- */
- const signal_delete = 'delete';
-
- /**
- * parameters definitions for signals
- */
- const signal_param_path = 'path';
- const signal_param_oldpath = 'oldpath';
- const signal_param_newpath = 'newpath';
-
- /**
- * run - changing this flag to false in hook handler will cancel event
- */
- const signal_param_run = 'run';
-
- /**
- * get the mountpoint of the storage object for a path
- ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
- *
- * @param string path
- * @return string
- */
+ /**
+ * classname which used for hooks handling
+ * used as signalclass in OC_Hooks::emit()
+ */
+ const CLASSNAME = 'OC_Filesystem';
+
+ /**
+ * signalname emited before file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_rename = 'rename';
+
+ /**
+ * signal emited after file renaming
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_rename = 'post_rename';
+
+ /**
+ * signal emited before file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_create = 'create';
+
+ /**
+ * signal emited after file/dir creation
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_post_create = 'post_create';
+
+ /**
+ * signal emits before file/dir copy
+ * @param oldpath
+ * @param newpath
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_copy = 'copy';
+
+ /**
+ * signal emits after file/dir copy
+ * @param oldpath
+ * @param newpath
+ */
+ const signal_post_copy = 'post_copy';
+
+ /**
+ * signal emits before file/dir save
+ * @param path
+ * @param run changing this flag to false in hook handler will cancel event
+ */
+ const signal_write = 'write';
+
+ /**
+ * signal emits after file/dir save
+ * @param path
+ */
+ const signal_post_write = 'post_write';
+
+ /**
+ * signal emits when reading file/dir
+ * @param path
+ */
+ const signal_read = 'read';
+
+ /**
+ * signal emits when removing file/dir
+ * @param path
+ */
+ const signal_delete = 'delete';
+
+ /**
+ * parameters definitions for signals
+ */
+ const signal_param_path = 'path';
+ const signal_param_oldpath = 'oldpath';
+ const signal_param_newpath = 'newpath';
+
+ /**
+ * run - changing this flag to false in hook handler will cancel event
+ */
+ const signal_param_run = 'run';
+
+ /**
+ * get the mountpoint of the storage object for a path
+ ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account
+ *
+ * @param string path
+ * @return string
+ */
static public function getMountPoint($path){
OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path));
if(!$path){
@@ -452,8 +452,8 @@ class OC_Filesystem{
static public function getMimeType($path){
return self::$defaultInstance->getMimeType($path);
}
- static public function hash($type,$path){
- return self::$defaultInstance->hash($type,$path);
+ static public function hash($type,$path, $raw = false){
+ return self::$defaultInstance->hash($type,$path, $raw);
}
static public function free_space($path='/'){
@@ -475,7 +475,8 @@ class OC_Filesystem{
static public function removeETagHook($params) {
$path=$params['path'];
- OC_Connector_Sabre_Node::removeETagPropertyForFile($path);
+ OC_Connector_Sabre_Node::removeETagPropertyForPath($path);
+ OC_Connector_Sabre_Node::removeETagPropertyForPath(dirname($path));
}
}
OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook');
diff --git a/lib/filesystemview.php b/lib/filesystemview.php
index a23d7bbe7fd..3c989d7c36f 100644
--- a/lib/filesystemview.php
+++ b/lib/filesystemview.php
@@ -22,19 +22,19 @@
/**
- * Class to provide access to ownCloud filesystem via a "view", and methods for
- * working with files within that view (e.g. read, write, delete, etc.). Each
- * view is restricted to a set of directories via a virtual root. The default view
- * uses the currently logged in user's data directory as root (parts of
+ * Class to provide access to ownCloud filesystem via a "view", and methods for
+ * working with files within that view (e.g. read, write, delete, etc.). Each
+ * view is restricted to a set of directories via a virtual root. The default view
+ * uses the currently logged in user's data directory as root (parts of
* OC_Filesystem are merely a wrapper for OC_FilesystemView).
- *
+ *
* Apps that need to access files outside of the user data folders (to modify files
* belonging to a user other than the one currently logged in, for example) should
* use this class directly rather than using OC_Filesystem, or making use of PHP's
- * built-in file manipulation functions. This will ensure all hooks and proxies
+ * built-in file manipulation functions. This will ensure all hooks and proxies
* are triggered correctly.
*
- * Filesystem functions are not called directly; they are passed to the correct
+ * Filesystem functions are not called directly; they are passed to the correct
* OC_Filestorage object
*/
@@ -43,11 +43,11 @@ class OC_FilesystemView {
private $internal_path_cache=array();
private $storage_cache=array();
- public function __construct($root){
+ public function __construct($root) {
$this->fakeRoot=$root;
}
- public function getAbsolutePath($path){
+ public function getAbsolutePath($path) {
if(!$path){
$path='/';
}
@@ -63,9 +63,9 @@ class OC_FilesystemView {
* @param string fakeRoot
* @return bool
*/
- public function chroot($fakeRoot){
+ public function chroot($fakeRoot) {
if(!$fakeRoot==''){
- if($fakeRoot[0]!=='/'){
+ if($fakeRoot[0]!=='/') {
$fakeRoot='/'.$fakeRoot;
}
}
@@ -76,7 +76,7 @@ class OC_FilesystemView {
* get the fake root
* @return string
*/
- public function getRoot(){
+ public function getRoot() {
return $this->fakeRoot;
}
@@ -85,7 +85,7 @@ class OC_FilesystemView {
* @param string path
* @return bool
*/
- public function getInternalPath($path){
+ public function getInternalPath($path) {
if (!isset($this->internal_path_cache[$path])) {
$this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path));
}
@@ -97,23 +97,23 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getRelativePath($path){
- if($this->fakeRoot==''){
+ public function getRelativePath($path) {
+ if($this->fakeRoot=='') {
return $path;
}
- if(strpos($path,$this->fakeRoot)!==0){
+ if(strpos($path, $this->fakeRoot)!==0) {
return null;
}else{
- return substr($path,strlen($this->fakeRoot));
+ return substr($path, strlen($this->fakeRoot));
}
}
-
+
/**
* get the storage object for a path
* @param string path
* @return OC_Filestorage
*/
- public function getStorage($path){
+ public function getStorage($path) {
if (!isset($this->storage_cache[$path])) {
$this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path));
}
@@ -127,7 +127,7 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getMountPoint($path){
+ public function getMountPoint($path) {
return OC_Filesystem::getMountPoint($this->getAbsolutePath($path));
}
@@ -137,55 +137,55 @@ class OC_FilesystemView {
* @param string path
* @return string
*/
- public function getLocalFile($path){
- $parent=substr($path,0,strrpos($path,'/'));
- if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)){
+ public function getLocalFile($path) {
+ $parent=substr($path, 0, strrpos($path,'/'));
+ if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) {
return $storage->getLocalFile($this->getInternalPath($path));
}
}
/**
- * the following functions operate with arguments and return values identical
- * to those of their PHP built-in equivalents. Mostly they are merely wrappers
+ * the following functions operate with arguments and return values identical
+ * to those of their PHP built-in equivalents. Mostly they are merely wrappers
* for OC_Filestorage via basicOperation().
*/
- public function mkdir($path){
- return $this->basicOperation('mkdir',$path,array('create','write'));
+ public function mkdir($path) {
+ return $this->basicOperation('mkdir', $path, array('create', 'write'));
}
- public function rmdir($path){
- return $this->basicOperation('rmdir',$path,array('delete'));
+ public function rmdir($path) {
+ return $this->basicOperation('rmdir', $path, array('delete'));
}
- public function opendir($path){
- return $this->basicOperation('opendir',$path,array('read'));
+ public function opendir($path) {
+ return $this->basicOperation('opendir', $path, array('read'));
}
- public function readdir($handle){
+ public function readdir($handle) {
$fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) );
return $fsLocal->readdir( $handle );
}
- public function is_dir($path){
+ public function is_dir($path) {
if($path=='/'){
return true;
}
- return $this->basicOperation('is_dir',$path);
+ return $this->basicOperation('is_dir', $path);
}
- public function is_file($path){
+ public function is_file($path) {
if($path=='/'){
return false;
}
- return $this->basicOperation('is_file',$path);
+ return $this->basicOperation('is_file', $path);
}
- public function stat($path){
- return $this->basicOperation('stat',$path);
+ public function stat($path) {
+ return $this->basicOperation('stat', $path);
}
- public function filetype($path){
- return $this->basicOperation('filetype',$path);
+ public function filetype($path) {
+ return $this->basicOperation('filetype', $path);
}
- public function filesize($path){
- return $this->basicOperation('filesize',$path);
+ public function filesize($path) {
+ return $this->basicOperation('filesize', $path);
}
- public function readfile($path){
+ public function readfile($path) {
@ob_end_clean();
- $handle=$this->fopen($path,'rb');
+ $handle=$this->fopen($path, 'rb');
if ($handle) {
$chunkSize = 8192;// 8 MB chunks
while (!feof($handle)) {
@@ -197,137 +197,210 @@ class OC_FilesystemView {
}
return false;
}
- public function is_readable($path){
- return $this->basicOperation('is_readable',$path);
+ public function is_readable($path) {
+ return $this->basicOperation('is_readable', $path);
}
- public function is_writable($path){
- return $this->basicOperation('is_writable',$path);
+ public function is_writable($path) {
+ return $this->basicOperation('is_writable', $path);
}
- public function file_exists($path){
+ public function file_exists($path) {
if($path=='/'){
return true;
}
- return $this->basicOperation('file_exists',$path);
+ return $this->basicOperation('file_exists', $path);
}
- public function filectime($path){
- return $this->basicOperation('filectime',$path);
+ public function filectime($path) {
+ return $this->basicOperation('filectime', $path);
}
- public function filemtime($path){
- return $this->basicOperation('filemtime',$path);
+ public function filemtime($path) {
+ return $this->basicOperation('filemtime', $path);
}
- public function touch($path, $mtime=null){
+ public function touch($path, $mtime=null) {
return $this->basicOperation('touch', $path, array('write'), $mtime);
}
- public function file_get_contents($path){
- return $this->basicOperation('file_get_contents',$path,array('read'));
- }
- public function file_put_contents($path,$data){
- if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier
- $exists=$this->file_exists($path);
- $run=true;
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
+ public function file_get_contents($path) {
+ return $this->basicOperation('file_get_contents', $path, array('read'));
+ }
+ public function file_put_contents($path, $data) {
+ if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier
+ $exists = $this->file_exists($path);
+ $run = true;
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_create,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
- if(!$run){
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_write,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ if(!$run) {
return false;
}
- $target=$this->fopen($path,'w');
- if($target){
- $count=OC_Helper::streamCopy($data,$target);
+ $target=$this->fopen($path, 'w');
+ if($target) {
+ $count=OC_Helper::streamCopy($data, $target);
fclose($target);
fclose($data);
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path));
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_create,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path));
- return $count>0;
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_write,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
+ return $count > 0;
}else{
return false;
}
}else{
- return $this->basicOperation('file_put_contents',$path,array('create','write'),$data);
+ return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data);
}
}
- public function unlink($path){
- return $this->basicOperation('unlink',$path,array('delete'));
+ public function unlink($path) {
+ return $this->basicOperation('unlink', $path, array('delete'));
}
public function deleteAll( $directory, $empty = false ) {
return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty );
}
- public function rename($path1,$path2){
- $absolutePath1=$this->getAbsolutePath($path1);
- $absolutePath2=$this->getAbsolutePath($path2);
- if(OC_FileProxy::runPreProxies('rename',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
- $path1=$this->getRelativePath($absolutePath1);
- $path2=$this->getRelativePath($absolutePath2);
- if($path1==null or $path2==null){
+ public function rename($path1, $path2) {
+ $absolutePath1 = $this->getAbsolutePath($path1);
+ $absolutePath2 = $this->getAbsolutePath($path2);
+ if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ $path1 = $this->getRelativePath($absolutePath1);
+ $path2 = $this->getRelativePath($absolutePath2);
+ if($path1 == null or $path2 == null) {
return false;
}
$run=true;
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
- if($run){
- $mp1=$this->getMountPoint($path1);
- $mp2=$this->getMountPoint($path2);
- if($mp1==$mp2){
- if($storage=$this->getStorage($path1)){
- $result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ if($run) {
+ $mp1 = $this->getMountPoint($path1);
+ $mp2 = $this->getMountPoint($path2);
+ if($mp1 == $mp2) {
+ if($storage = $this->getStorage($path1)) {
+ $result = $storage->rename($this->getInternalPath($path1), $this->getInternalPath($path2));
}
- }else{
- $source=$this->fopen($path1,'r');
- $target=$this->fopen($path2,'w');
- $count=OC_Helper::streamCopy($source,$target);
- $storage1=$this->getStorage($path1);
+ } else {
+ $source = $this->fopen($path1, 'r');
+ $target = $this->fopen($path2, 'w');
+ $count = OC_Helper::streamCopy($source, $target);
+ $storage1 = $this->getStorage($path1);
$storage1->unlink($this->getInternalPath($path1));
- $result=$count>0;
+ $result = $count>0;
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_rename,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath => $path2
+ )
+ );
return $result;
}
}
}
- public function copy($path1,$path2){
- $absolutePath1=$this->getAbsolutePath($path1);
- $absolutePath2=$this->getAbsolutePath($path2);
- if(OC_FileProxy::runPreProxies('copy',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){
- $path1=$this->getRelativePath($absolutePath1);
- $path2=$this->getRelativePath($absolutePath2);
- if($path1==null or $path2==null){
+ public function copy($path1, $path2) {
+ $absolutePath1 = $this->getAbsolutePath($path1);
+ $absolutePath2 = $this->getAbsolutePath($path2);
+ if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) {
+ $path1 = $this->getRelativePath($absolutePath1);
+ $path2 = $this->getRelativePath($absolutePath2);
+ if($path1 == null or $path2 == null) {
return false;
}
$run=true;
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_copy,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath=>$path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
$exists=$this->file_exists($path2);
- if($run and !$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
+ if($run and !$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_create,
+ array(
+ OC_Filesystem::signal_param_path => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- if($run){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run));
+ if($run) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_write,
+ array(
+ OC_Filesystem::signal_param_path => $path2,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
}
- if($run){
+ if($run) {
$mp1=$this->getMountPoint($path1);
$mp2=$this->getMountPoint($path2);
- if($mp1==$mp2){
- if($storage=$this->getStorage($path1)){
- $result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2));
+ if($mp1 == $mp2){
+ if($storage = $this->getStorage($path1)) {
+ $result=$storage->copy($this->getInternalPath($path1), $this->getInternalPath($path2));
}
- }else{
- $source=$this->fopen($path1,'r');
- $target=$this->fopen($path2,'w');
- $result=OC_Helper::streamCopy($source,$target);
+ } else {
+ $source = $this->fopen($path1, 'r');
+ $target = $this->fopen($path2, 'w');
+ $result = OC_Helper::streamCopy($source, $target);
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2));
- if(!$exists){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_copy,
+ array(
+ OC_Filesystem::signal_param_oldpath => $path1,
+ OC_Filesystem::signal_param_newpath=>$path2
+ )
+ );
+ if(!$exists) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_create,
+ array(OC_Filesystem::signal_param_path => $path2)
+ );
}
- OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path2));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_post_write,
+ array( OC_Filesystem::signal_param_path => $path2)
+ );
return $result;
}
}
}
- public function fopen($path,$mode){
+ public function fopen($path, $mode) {
$hooks=array();
- switch($mode){
+ switch($mode) {
case 'r':
case 'rb':
$hooks[]='read';
@@ -355,49 +428,68 @@ class OC_FilesystemView {
OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR);
}
- return $this->basicOperation('fopen',$path,$hooks,$mode);
+ return $this->basicOperation('fopen', $path, $hooks, $mode);
}
- public function toTmpFile($path){
- if(OC_Filesystem::isValidPath($path)){
- $source=$this->fopen($path,'r');
- if($source){
+ public function toTmpFile($path) {
+ if(OC_Filesystem::isValidPath($path)) {
+ $source = $this->fopen($path, 'r');
+ if($source) {
$extension='';
- $extOffset=strpos($path,'.');
+ $extOffset=strpos($path, '.');
if($extOffset !== false) {
- $extension=substr($path,strrpos($path,'.'));
+ $extension=substr($path, strrpos($path,'.'));
}
- $tmpFile=OC_Helper::tmpFile($extension);
- file_put_contents($tmpFile,$source);
+ $tmpFile = OC_Helper::tmpFile($extension);
+ file_put_contents($tmpFile, $source);
return $tmpFile;
}
}
}
- public function fromTmpFile($tmpFile,$path){
- if(OC_Filesystem::isValidPath($path)){
- if(!$tmpFile){
+ public function fromTmpFile($tmpFile, $path) {
+ if(OC_Filesystem::isValidPath($path)) {
+ if(!$tmpFile) {
debug_print_backtrace();
}
- $source=fopen($tmpFile,'r');
- if($source){
- $this->file_put_contents($path,$source);
+ $source=fopen($tmpFile, 'r');
+ if($source) {
+ $this->file_put_contents($path, $source);
unlink($tmpFile);
return true;
- }else{
+ } else {
}
- }else{
+ } else {
return false;
}
}
- public function getMimeType($path){
- return $this->basicOperation('getMimeType',$path);
- }
- public function hash($type,$path){
- return $this->basicOperation('hash',$path,array('read'),$type);
+ public function getMimeType($path) {
+ return $this->basicOperation('getMimeType', $path);
+ }
+ public function hash($type, $path, $raw = false) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) {
+ $path = $this->getRelativePath($absolutePath);
+ if ($path == null) {
+ return false;
+ }
+ if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ OC_Filesystem::signal_read,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
+ }
+ if ($storage = $this->getStorage($path)) {
+ $result = $storage->hash($type, $this->getInternalPath($path), $raw);
+ $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result);
+ return $result;
+ }
+ }
+ return null;
}
- public function free_space($path='/'){
- return $this->basicOperation('free_space',$path);
+ public function free_space($path='/') {
+ return $this->basicOperation('free_space', $path);
}
/**
@@ -407,41 +499,56 @@ class OC_FilesystemView {
* @param array (optional) hooks
* @param mixed (optional) $extraParam
* @return mixed
- *
- * This method takes requests for basic filesystem functions (e.g. reading & writing
- * files), processes hooks and proxies, sanitises paths, and finally passes them on to
+ *
+ * This method takes requests for basic filesystem functions (e.g. reading & writing
+ * files), processes hooks and proxies, sanitises paths, and finally passes them on to
* OC_Filestorage for delegation to a storage backend for execution
*/
- private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){
- $absolutePath=$this->getAbsolutePath($path);
- if(OC_FileProxy::runPreProxies($operation,$absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)){
- $path=$this->getRelativePath($absolutePath);
- if($path==null){
+ private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) {
+ $absolutePath = $this->getAbsolutePath($path);
+ if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) {
+ $path = $this->getRelativePath($absolutePath);
+ if($path == null) {
return false;
}
- $internalPath=$this->getInternalPath($path);
- $run=true;
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
- foreach($hooks as $hook){
- if($hook!='read'){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run));
- }else{
- OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path));
+ $internalPath = $this->getInternalPath($path);
+ $run = true;
+ if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
+ foreach($hooks as $hook) {
+ if($hook!='read') {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ $hook,
+ array(
+ OC_Filesystem::signal_param_path => $path,
+ OC_Filesystem::signal_param_run => &$run
+ )
+ );
+ } else {
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ $hook,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
}
}
- if($run and $storage=$this->getStorage($path)){
- if(!is_null($extraParam)){
- $result=$storage->$operation($internalPath,$extraParam);
- }else{
- $result=$storage->$operation($internalPath);
+ if($run and $storage = $this->getStorage($path)) {
+ if(!is_null($extraParam)) {
+ $result = $storage->$operation($internalPath, $extraParam);
+ } else {
+ $result = $storage->$operation($internalPath);
}
- $result=OC_FileProxy::runPostProxies($operation,$this->getAbsolutePath($path),$result);
- if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){
- if($operation!='fopen'){//no post hooks for fopen, the file stream is still open
- foreach($hooks as $hook){
+ $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result);
+ if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) {
+ if($operation!='fopen') {//no post hooks for fopen, the file stream is still open
+ foreach($hooks as $hook) {
if($hook!='read'){
- OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path));
+ OC_Hook::emit(
+ OC_Filesystem::CLASSNAME,
+ 'post_'.$hook,
+ array( OC_Filesystem::signal_param_path => $path)
+ );
}
}
}
@@ -457,7 +564,7 @@ class OC_FilesystemView {
* @param int $time
* @return bool
*/
- public function hasUpdated($path,$time){
- return $this->basicOperation('hasUpdated',$path,array(),$time);
+ public function hasUpdated($path, $time) {
+ return $this->basicOperation('hasUpdated', $path, array(), $time);
}
}
diff --git a/lib/group.php b/lib/group.php
index fb280c157e8..7b137f0f8f1 100644
--- a/lib/group.php
+++ b/lib/group.php
@@ -43,7 +43,7 @@ class OC_Group {
* @returns true/false
*/
public static function useBackend( $backend ){
- if($backend instanceof OC_Group_Backend){
+ if($backend instanceof OC_Group_Interface){
self::$_usedBackends[]=$backend;
}
}
@@ -168,7 +168,7 @@ class OC_Group {
if($run){
$succes=false;
-
+
//add the user to the all backends that have the group
foreach(self::$_usedBackends as $backend){
if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP))
@@ -245,7 +245,7 @@ class OC_Group {
asort($groups);
return $groups;
}
-
+
/**
* check if a group exists
* @param string $gid
@@ -259,7 +259,7 @@ class OC_Group {
}
return false;
}
-
+
/**
* @brief get a list of all users in a group
* @returns array with user ids
diff --git a/lib/group/backend.php b/lib/group/backend.php
index 24778afd1e5..ebc078f152a 100644
--- a/lib/group/backend.php
+++ b/lib/group/backend.php
@@ -37,7 +37,7 @@ define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000);
/**
* Abstract base class for user management
*/
-abstract class OC_Group_Backend {
+abstract class OC_Group_Backend implements OC_Group_Interface {
protected $possibleActions = array(
OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup',
OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup',
diff --git a/lib/group/interface.php b/lib/group/interface.php
new file mode 100644
index 00000000000..7cca6061e10
--- /dev/null
+++ b/lib/group/interface.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * ownCloud - group interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_Group_Interface {
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_GROUP_BACKEND_CREATE_GROUP etc.
+ */
+ public function implementsActions($actions);
+
+ /**
+ * @brief is user in group?
+ * @param $uid uid of the user
+ * @param $gid gid of the group
+ * @returns true/false
+ *
+ * Checks whether the user is member of a group or not.
+ */
+ public function inGroup($uid, $gid);
+
+ /**
+ * @brief Get all groups a user belongs to
+ * @param $uid Name of the user
+ * @returns array with group names
+ *
+ * This function fetches all groups a user belongs to. It does not check
+ * if the user exists at all.
+ */
+ public function getUserGroups($uid);
+
+ /**
+ * @brief get a list of all groups
+ * @returns array with group names
+ *
+ * Returns a list with all groups
+ */
+ public function getGroups();
+
+ /**
+ * check if a group exists
+ * @param string $gid
+ * @return bool
+ */
+ public function groupExists($gid);
+
+ /**
+ * @brief get a list of all users in a group
+ * @returns array with user ids
+ */
+ public function usersInGroup($gid);
+
+} \ No newline at end of file
diff --git a/lib/helper.php b/lib/helper.php
index c4f7e8b2e19..666bc6badfc 100644
--- a/lib/helper.php
+++ b/lib/helper.php
@@ -175,10 +175,8 @@ class OC_Helper {
*/
public static function mimetypeIcon( $mimetype ){
$alias=array('application/xml'=>'code/xml');
-// echo $mimetype;
if(isset($alias[$mimetype])){
$mimetype=$alias[$mimetype];
-// echo $mimetype;
}
// Replace slash with a minus
$mimetype = str_replace( "/", "-", $mimetype );
@@ -345,18 +343,24 @@ class OC_Helper {
*/
static function getMimeType($path){
$isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://');
- $mimeType='application/octet-stream';
- if ($mimeType=='application/octet-stream') {
- self::$mimetypes = include('mimetypes.fixlist.php');
- $extension=strtolower(strrchr(basename($path), "."));
- $extension=substr($extension,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
- }
if (@is_dir($path)) {
// directories are easy
return "httpd/unix-directory";
}
+
+ if(strpos($path,'.')){
+ //try to guess the type by the file extension
+ if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
+ self::$mimetypes=include('mimetypes.list.php');
+ }
+ $extension=strtolower(strrchr(basename($path), "."));
+ $extension=substr($extension,1);//remove leading .
+ $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
+ }else{
+ $mimeType='application/octet-stream';
+ }
+
if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){
$info = @strtolower(finfo_file($finfo,$path));
if($info){
@@ -385,15 +389,6 @@ class OC_Helper {
}
}
- if ($mimeType=='application/octet-stream') {
- // Fallback solution: (try to guess the type by the file extension
- if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){
- self::$mimetypes=include('mimetypes.list.php');
- }
- $extension=strtolower(strrchr(basename($path), "."));
- $extension=substr($extension,1);//remove leading .
- $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream';
- }
return $mimeType;
}
@@ -684,4 +679,30 @@ class OC_Helper {
}
return $subject;
}
+
+ /**
+ * @brief performs a search in a nested array
+ * @param haystack the array to be searched
+ * @param needle the search string
+ * @param $index optional, only search this key name
+ * @return the key of the matching field, otherwise false
+ *
+ * performs a search in a nested array
+ *
+ * taken from http://www.php.net/manual/en/function.array-search.php#97645
+ */
+ public static function recursiveArraySearch($haystack, $needle, $index = null) {
+ $aIt = new RecursiveArrayIterator($haystack);
+ $it = new RecursiveIteratorIterator($aIt);
+
+ while($it->valid()) {
+ if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) {
+ return $aIt->key();
+ }
+
+ $it->next();
+ }
+
+ return false;
+ }
}
diff --git a/lib/image.php b/lib/image.php
index c438b3d67f6..90c64320a7c 100644
--- a/lib/image.php
+++ b/lib/image.php
@@ -23,12 +23,12 @@
//From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php
if ( ! function_exists( 'exif_imagetype' ) ) {
- function exif_imagetype ( $filename ) {
- if ( ( $info = getimagesize( $filename ) ) !== false ) {
- return $info[2];
- }
- return false;
- }
+ function exif_imagetype ( $filename ) {
+ if ( ( $info = getimagesize( $filename ) ) !== false ) {
+ return $info[2];
+ }
+ return false;
+ }
}
function ellipsis($str, $maxlen) {
@@ -66,7 +66,6 @@ class OC_Image {
public function __construct($imageref = null) {
//OC_Log::write('core',__METHOD__.'(): start', OC_Log::DEBUG);
if(!extension_loaded('gd') || !function_exists('gd_info')) {
- //if(!function_exists('imagecreatefromjpeg')) {
OC_Log::write('core',__METHOD__.'(): GD module not installed', OC_Log::ERROR);
return false;
}
diff --git a/lib/installer.php b/lib/installer.php
index 00feb6d4709..a8b56cb34f2 100644
--- a/lib/installer.php
+++ b/lib/installer.php
@@ -126,19 +126,19 @@ class OC_Installer{
return false;
}
$info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true);
- // check the code for not allowed calls
- if(!OC_Installer::checkCode($info['id'],$extractDir)){
+ // check the code for not allowed calls
+ if(!OC_Installer::checkCode($info['id'],$extractDir)){
OC_Log::write('core','App can\'t be installed because of not allowed code in the App',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
- return false;
+ return false;
}
- // check if the app is compatible with this version of ownCloud
+ // check if the app is compatible with this version of ownCloud
$version=OC_Util::getVersion();
- if(!isset($info['require']) or ($version[0]>$info['require'])){
+ if(!isset($info['require']) or ($version[0]>$info['require'])){
OC_Log::write('core','App can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR);
OC_Helper::rmdirr($extractDir);
- return false;
+ return false;
}
//check if an app with the same id is already installed
@@ -339,12 +339,12 @@ class OC_Installer{
}
- /**
- * check the code of an app with some static code checks
- * @param string $folder the folder of the app to check
- * @returns true for app is o.k. and false for app is not o.k.
- */
- public static function checkCode($appname,$folder){
+ /**
+ * check the code of an app with some static code checks
+ * @param string $folder the folder of the app to check
+ * @returns true for app is o.k. and false for app is not o.k.
+ */
+ public static function checkCode($appname,$folder){
$blacklist=array(
'exec(',
@@ -377,9 +377,7 @@ class OC_Installer{
return true;
}else{
- return true;
+ return true;
}
- }
-
-
+ }
}
diff --git a/lib/json.php b/lib/json.php
index b0d3d918657..3d9d5c96fa3 100644
--- a/lib/json.php
+++ b/lib/json.php
@@ -106,12 +106,12 @@ class OC_JSON{
* Encode and print $data in json format
*/
public static function encodedPrint($data,$setContentType=true){
- // Disable mimesniffing, don't move this to setContentTypeHeader!
- header( 'X-Content-Type-Options: nosniff' );
- if($setContentType){
- self::setContentTypeHeader();
- }
- array_walk_recursive($data, array('OC_JSON', 'to_string'));
- echo json_encode($data);
+ // Disable mimesniffing, don't move this to setContentTypeHeader!
+ header( 'X-Content-Type-Options: nosniff' );
+ if($setContentType){
+ self::setContentTypeHeader();
+ }
+ array_walk_recursive($data, array('OC_JSON', 'to_string'));
+ echo json_encode($data);
}
}
diff --git a/lib/mimetypes.fixlist.php b/lib/mimetypes.fixlist.php
deleted file mode 100644
index 13e3f16b369..00000000000
--- a/lib/mimetypes.fixlist.php
+++ /dev/null
@@ -1,22 +0,0 @@
-<?php
-return array(
- 'ics'=>'text/calendar',
- 'ical'=>'text/calendar',
- 'js'=>'application/javascript',
- 'odt'=>'application/vnd.oasis.opendocument.text',
- 'ods'=>'application/vnd.oasis.opendocument.spreadsheet',
- 'odg'=>'application/vnd.oasis.opendocument.graphics',
- 'odp'=>'application/vnd.oasis.opendocument.presentation',
- 'pl'=>'text/x-script.perl',
- 'py'=>'text/x-script.phyton',
- 'vcf' => 'text/vcard',
- 'vcard' => 'text/vcard',
- 'doc'=>'application/msword',
- 'docx'=>'application/msword',
- 'xls'=>'application/msexcel',
- 'xlsx'=>'application/msexcel',
- 'ppt'=>'application/mspowerpoint',
- 'pptx'=>'application/mspowerpoint',
- 'sgf' => 'application/sgf',
- 'cdr' => 'application/coreldraw'
-);
diff --git a/lib/mimetypes.list.php b/lib/mimetypes.list.php
index ccf47999b1c..f7207493f7f 100644
--- a/lib/mimetypes.list.php
+++ b/lib/mimetypes.list.php
@@ -78,5 +78,16 @@ return array(
'mpeg'=>'video/mpeg',
'mov'=>'video/quicktime',
'webm'=>'video/webm',
- 'wmv'=>'video/x-ms-asf'
+ 'wmv'=>'video/x-ms-asf',
+ 'py'=>'text/x-script.phyton',
+ 'vcf' => 'text/vcard',
+ 'vcard' => 'text/vcard',
+ 'doc'=>'application/msword',
+ 'docx'=>'application/msword',
+ 'xls'=>'application/msexcel',
+ 'xlsx'=>'application/msexcel',
+ 'ppt'=>'application/mspowerpoint',
+ 'pptx'=>'application/mspowerpoint',
+ 'sgf' => 'application/sgf',
+ 'cdr' => 'application/coreldraw',
);
diff --git a/lib/minimizer.php b/lib/minimizer.php
index 3bf5ff9980b..3dc89e331a6 100644
--- a/lib/minimizer.php
+++ b/lib/minimizer.php
@@ -46,3 +46,13 @@ abstract class OC_Minimizer {
echo $out;
}
}
+
+if (!function_exists('gzdecode')) {
+ function gzdecode($data,$maxlength=null,&$filename='',&$error='')
+ {
+ if (strcmp(substr($data,0,9),"\x1f\x8b\x8\0\0\0\0\0\0")) {
+ return null; // Not the GZIP format we expect (See RFC 1952)
+ }
+ return gzinflate(substr($data,10,-8));
+ }
+}
diff --git a/lib/ocs.php b/lib/ocs.php
index 77dd437d6c6..3157aae99e6 100644
--- a/lib/ocs.php
+++ b/lib/ocs.php
@@ -4,7 +4,9 @@
* ownCloud
*
* @author Frank Karlitschek
+* @author Michael Gapczynski
* @copyright 2012 Frank Karlitschek frank@owncloud.org
+* @copyright 2012 Michael Gapczynski mtgap@owncloud.com
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
@@ -29,425 +31,453 @@
*/
class OC_OCS {
- /**
- * reads input date from get/post/cookies and converts the date to a special data-type
- *
- * @param variable $key
- * @param variable-type $type
- * @param priority $getpriority
- * @param default $default
- * @return data
- */
- public static function readData($key,$type='raw',$getpriority=false,$default='') {
- if($getpriority) {
- if(isset($_GET[$key])) {
- $data=$_GET[$key];
- } elseif(isset($_POST[$key])) {
- $data=$_POST[$key];
- } else {
- if($default=='') {
- if(($type=='int') or ($type=='float')) $data=0; else $data='';
- } else {
- $data=$default;
- }
- }
- } else {
- if(isset($_POST[$key])) {
- $data=$_POST[$key];
- } elseif(isset($_GET[$key])) {
- $data=$_GET[$key];
- } elseif(isset($_COOKIE[$key])) {
- $data=$_COOKIE[$key];
- } else {
- if($default=='') {
- if(($type=='int') or ($type=='float')) $data=0; else $data='';
- } else {
- $data=$default;
- }
- }
- }
-
- if($type=='raw') return($data);
- elseif($type=='text') return(addslashes(strip_tags($data)));
- elseif($type=='int') { $data = (int) $data; return($data); }
- elseif($type=='float') { $data = (float) $data; return($data); }
- elseif($type=='array') { $data = $data; return($data); }
- }
-
-
- /**
- main function to handle the REST request
- **/
- public static function handle() {
-
- // overwrite the 404 error page returncode
- header("HTTP/1.0 200 OK");
-
-
- if($_SERVER['REQUEST_METHOD'] == 'GET') {
- $method='get';
- }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
- $method='put';
- }elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
- $method='post';
- }else{
- echo('internal server error: method not supported');
- exit();
- }
-
- // preprocess url
- $url=$_SERVER['REQUEST_URI'];
- if(substr($url,(strlen($url)-1))<>'/') $url.='/';
- $ex=explode('/',$url);
- $paracount=count($ex);
-
- // eventhandler
- // CONFIG
- // apiconfig - GET - CONFIG
- if(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php') and (strtolower($ex[$paracount-2])=='config')){
- $format=OC_OCS::readdata('format','text');
- OC_OCS::apiconfig($format);
-
- // PERSON
- // personcheck - POST - PERSON/CHECK
- }elseif(($method=='post') and (strtolower($ex[$paracount-4])=='v1.php') and (strtolower($ex[$paracount-3])=='person') and (strtolower($ex[$paracount-2])=='check')){
- $format=OC_OCS::readdata('format','text');
- $login=OC_OCS::readdata('login','text');
- $passwd=OC_OCS::readdata('password','text');
- OC_OCS::personcheck($format,$login,$passwd);
-
- // ACTIVITY
- // activityget - GET ACTIVITY page,pagesize als urlparameter
- }elseif(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){
- $format=OC_OCS::readdata('format','text');
- $page=OC_OCS::readdata('page','int');
- $pagesize=OC_OCS::readdata('pagesize','int');
- if($pagesize<1 or $pagesize>100) $pagesize=10;
- OC_OCS::activityget($format,$page,$pagesize);
-
- // activityput - POST ACTIVITY
- }elseif(($method=='post') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){
- $format=OC_OCS::readdata('format','text');
- $message=OC_OCS::readdata('message','text');
- OC_OCS::activityput($format,$message);
-
- // PRIVATEDATA
- // get - GET DATA
- }elseif(($method=='get') and (strtolower($ex[$paracount-4])=='v1.php')and (strtolower($ex[$paracount-2])=='getattribute')){
- $format=OC_OCS::readdata('format','text');
- OC_OCS::privateDataGet($format);
-
- }elseif(($method=='get') and (strtolower($ex[$paracount-5])=='v1.php')and (strtolower($ex[$paracount-3])=='getattribute')){
- $format=OC_OCS::readdata('format','text');
- $app=$ex[$paracount-2];
- OC_OCS::privateDataGet($format, $app);
- }elseif(($method=='get') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='getattribute')){
- $format=OC_OCS::readdata('format','text');
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- OC_OCS::privateDataGet($format, $app,$key);
-
- // set - POST DATA
- }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='setattribute')){
- $format=OC_OCS::readdata('format','text');
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- $value=OC_OCS::readdata('value','text');
- OC_OCS::privatedataset($format, $app, $key, $value);
- // delete - POST DATA
- }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='deleteattribute')){
- $format=OC_OCS::readdata('format','text');
- $key=$ex[$paracount-2];
- $app=$ex[$paracount-3];
- OC_OCS::privatedatadelete($format, $app, $key);
-
- }else{
- $format=OC_OCS::readdata('format','text');
- $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
- $txt.=OC_OCS::getdebugoutput();
- echo(OC_OCS::generatexml($format,'failed',999,$txt));
- }
- exit();
- }
-
- /**
- * generated some debug information to make it easier to find faild API calls
- * @return debug data string
- */
- private static function getDebugOutput() {
- $txt='';
- $txt.="debug output:\n";
- if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n";
- if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n";
- if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n";
- if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
- return($txt);
- }
-
- /**
- * checks if the user is authenticated
- * checks the IP whitlist, apikeys and login/password combination
- * if $forceuser is true and the authentication failed it returns an 401 http response.
- * if $forceuser is false and authentification fails it returns an empty username string
- * @param bool $forceuser
- * @return username string
- */
- private static function checkPassword($forceuser=true) {
- //valid user account ?
- if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
- if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
-
- if(empty($authuser)) {
- if($forceuser){
- header('WWW-Authenticate: Basic realm="your valid user account or api key"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
- }else{
- $identifieduser='';
- }
- }else{
- if(!OC_User::login($authuser,$authpw)){
- if($forceuser){
- header('WWW-Authenticate: Basic realm="your valid user account or api key"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
- }else{
- $identifieduser='';
- }
- }else{
- $identifieduser=$authuser;
- }
- }
-
- return($identifieduser);
- }
-
-
- /**
- * generates the xml or json response for the API call from an multidimenional data array.
- * @param string $format
- * @param string $status
- * @param string $statuscode
- * @param string $message
- * @param array $data
- * @param string $tag
- * @param string $tagattribute
- * @param int $dimension
- * @param int $itemscount
- * @param int $itemsperpage
- * @return string xml/json
- */
- private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') {
- if($format=='json') {
-
- $json=array();
- $json['status']=$status;
- $json['statuscode']=$statuscode;
- $json['message']=$message;
- $json['totalitems']=$itemscount;
- $json['itemsperpage']=$itemsperpage;
- $json['data']=$data;
- return(json_encode($json));
-
-
- }else{
- $txt='';
- $writer = xmlwriter_open_memory();
- xmlwriter_set_indent( $writer, 2 );
- xmlwriter_start_document($writer );
- xmlwriter_start_element($writer,'ocs');
- xmlwriter_start_element($writer,'meta');
- xmlwriter_write_element($writer,'status',$status);
- xmlwriter_write_element($writer,'statuscode',$statuscode);
- xmlwriter_write_element($writer,'message',$message);
- if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount);
- if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage);
- xmlwriter_end_element($writer);
- if($dimension=='0') {
- // 0 dimensions
- xmlwriter_write_element($writer,'data',$data);
-
- }elseif($dimension=='1') {
- xmlwriter_start_element($writer,'data');
- foreach($data as $key=>$entry) {
- xmlwriter_write_element($writer,$key,$entry);
- }
- xmlwriter_end_element($writer);
-
- }elseif($dimension=='2') {
- xmlwriter_start_element($writer,'data');
- foreach($data as $entry) {
- xmlwriter_start_element($writer,$tag);
- if(!empty($tagattribute)) {
- xmlwriter_write_attribute($writer,'details',$tagattribute);
- }
- foreach($entry as $key=>$value) {
- if(is_array($value)){
- foreach($value as $k=>$v) {
- xmlwriter_write_element($writer,$k,$v);
- }
- } else {
- xmlwriter_write_element($writer,$key,$value);
- }
- }
- xmlwriter_end_element($writer);
- }
- xmlwriter_end_element($writer);
-
- }elseif($dimension=='3') {
- xmlwriter_start_element($writer,'data');
- foreach($data as $entrykey=>$entry) {
- xmlwriter_start_element($writer,$tag);
- if(!empty($tagattribute)) {
- xmlwriter_write_attribute($writer,'details',$tagattribute);
- }
- foreach($entry as $key=>$value) {
- if(is_array($value)){
- xmlwriter_start_element($writer,$entrykey);
- foreach($value as $k=>$v) {
- xmlwriter_write_element($writer,$k,$v);
- }
- xmlwriter_end_element($writer);
- } else {
- xmlwriter_write_element($writer,$key,$value);
- }
- }
- xmlwriter_end_element($writer);
- }
- xmlwriter_end_element($writer);
- }elseif($dimension=='dynamic') {
- xmlwriter_start_element($writer,'data');
- OC_OCS::toxml($writer,$data,'comment');
- xmlwriter_end_element($writer);
- }
-
- xmlwriter_end_element($writer);
-
- xmlwriter_end_document( $writer );
- $txt.=xmlwriter_output_memory( $writer );
- unset($writer);
- return($txt);
- }
- }
-
- public static function toXml($writer,$data,$node) {
- foreach($data as $key => $value) {
- if (is_numeric($key)) {
- $key = $node;
- }
- if (is_array($value)){
- xmlwriter_start_element($writer,$key);
- OC_OCS::toxml($writer,$value,$node);
- xmlwriter_end_element($writer);
- }else{
- xmlwriter_write_element($writer,$key,$value);
- }
-
- }
- }
-
-
-
-
- /**
- * return the config data of this server
- * @param string $format
- * @return string xml/json
- */
- private static function apiConfig($format) {
- $xml['version']='1.5';
- $xml['website']='ownCloud';
- $xml['host']=OCP\Util::getServerHost();
- $xml['contact']='';
- $xml['ssl']='false';
- echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1));
- }
-
-
- /**
- * check if the provided login/apikey/password is valid
- * @param string $format
- * @param string $login
- * @param string $passwd
- * @return string xml/json
- */
- private static function personCheck($format,$login,$passwd) {
- if($login<>''){
- if(OC_User::login($login,$passwd)){
- $xml['person']['personid']=$login;
- echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2));
- }else{
- echo(OC_OCS::generatexml($format,'failed',102,'login not valid'));
- }
- }else{
- echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields'));
- }
- }
-
-
-
- // ACTIVITY API #############################################
-
- /**
- * get my activities
- * @param string $format
- * @param string $page
- * @param string $pagesize
- * @return string xml/json
- */
- private static function activityGet($format,$page,$pagesize) {
- $user=OC_OCS::checkpassword();
-
- //TODO
-
- $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
- echo($txt);
- }
-
- /**
- * submit a activity
- * @param string $format
- * @param string $message
- * @return string xml/json
- */
- private static function activityPut($format,$message) {
- // not implemented in ownCloud
- OC_OCS::checkpassword();
- echo(OC_OCS::generatexml($format,'ok',100,''));
- }
-
- // PRIVATEDATA API #############################################
-
- /**
- * get private data and create the xml for ocs
- * @param string $format
- * @param string $app
- * @param string $key
- * @return string xml/json
- */
- private static function privateDataGet($format,$app="",$key="") {
- $user=OC_OCS::checkpassword();
- $result=OC_OCS::getData($user,$app,$key);
- $xml=array();
- foreach($result as $i=>$log) {
- $xml[$i]['key']=$log['key'];
- $xml[$i]['app']=$log['app'];
- $xml[$i]['value']=$log['value'];
- }
-
-
- $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
- echo($txt);
- }
-
- /**
- * set private data referenced by $key to $value and generate the xml for ocs
- * @param string $format
- * @param string $app
- * @param string $key
- * @param string $value
- * @return string xml/json
- */
+ /**
+ * reads input date from get/post/cookies and converts the date to a special data-type
+ *
+ * @param string HTTP method to read the key from
+ * @param string Parameter to read
+ * @param string Variable type to format data
+ * @param mixed Default value to return if the key is not found
+ * @return mixed Data or if the key is not found and no default is set it will exit with a 400 Bad request
+ */
+ public static function readData($method, $key, $type = 'raw', $default = null) {
+ if ($method == 'get') {
+ if (isset($_GET[$key])) {
+ $data = $_GET[$key];
+ } else if (isset($default)) {
+ return $default;
+ } else {
+ $data = false;
+ }
+ } else if ($method == 'post') {
+ if (isset($_POST[$key])) {
+ $data = $_POST[$key];
+ } else if (isset($default)) {
+ return $default;
+ } else {
+ $data = false;
+ }
+ }
+ if ($data === false) {
+ echo self::generateXml('', 'fail', 400, 'Bad request. Please provide a valid '.$key);
+ exit();
+ } else {
+ // NOTE: Is the raw type necessary? It might be a little risky without sanitization
+ if ($type == 'raw') return $data;
+ elseif ($type == 'text') return OC_Util::sanitizeHTML($data);
+ elseif ($type == 'int') return (int) $data;
+ elseif ($type == 'float') return (float) $data;
+ elseif ($type == 'array') return OC_Util::sanitizeHTML($data);
+ else return OC_Util::sanitizeHTML($data);
+ }
+ }
+
+ /**
+ main function to handle the REST request
+ **/
+ public static function handle() {
+ // overwrite the 404 error page returncode
+ header("HTTP/1.0 200 OK");
+
+
+ if($_SERVER['REQUEST_METHOD'] == 'GET') {
+ $method='get';
+ }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') {
+ $method='put';
+ parse_str(file_get_contents("php://input"),$put_vars);
+ }elseif($_SERVER['REQUEST_METHOD'] == 'POST') {
+ $method='post';
+ }else{
+ echo('internal server error: method not supported');
+ exit();
+ }
+
+ // preprocess url
+ $url = strtolower($_SERVER['REQUEST_URI']);
+ if(substr($url,(strlen($url)-1))<>'/') $url.='/';
+ $ex=explode('/',$url);
+ $paracount=count($ex);
+ $format = self::readData($method, 'format', 'text', '');
+
+ // eventhandler
+ // CONFIG
+ // apiconfig - GET - CONFIG
+ if(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'config')){
+ OC_OCS::apiconfig($format);
+
+ // PERSON
+ // personcheck - POST - PERSON/CHECK
+ }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='person') and ($ex[$paracount-2] == 'check')){
+ $login = self::readData($method, 'login', 'text');
+ $passwd = self::readData($method, 'password', 'text');
+ OC_OCS::personcheck($format,$login,$passwd);
+
+ // ACTIVITY
+ // activityget - GET ACTIVITY page,pagesize als urlparameter
+ }elseif(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){
+ $page = self::readData($method, 'page', 'int', 0);
+ $pagesize = self::readData($method, 'pagesize','int', 10);
+ if($pagesize<1 or $pagesize>100) $pagesize=10;
+ OC_OCS::activityget($format,$page,$pagesize);
+
+ // activityput - POST ACTIVITY
+ }elseif(($method=='post') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){
+ $message = self::readData($method, 'message', 'text');
+ OC_OCS::activityput($format,$message);
+
+
+ // PRIVATEDATA
+ // get - GET DATA
+ }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-2] == 'getattribute')){
+ OC_OCS::privateDataGet($format);
+
+ }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-3] == 'getattribute')){
+ $app=$ex[$paracount-2];
+ OC_OCS::privateDataGet($format, $app);
+ }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'getattribute')){
+
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ OC_OCS::privateDataGet($format, $app,$key);
+
+ // set - POST DATA
+ }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'setattribute')){
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ $value = self::readData($method, 'value', 'text');
+ OC_OCS::privatedataset($format, $app, $key, $value);
+ // delete - POST DATA
+ }elseif(($method=='post') and ($ex[$paracount-6] =='v1.php') and ($ex[$paracount-4] == 'deleteattribute')){
+ $key=$ex[$paracount-2];
+ $app=$ex[$paracount-3];
+ OC_OCS::privatedatadelete($format, $app, $key);
+
+ // CLOUD
+ // systemWebApps
+ }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-4]=='cloud') and ($ex[$paracount-3] == 'system') and ($ex[$paracount-2] == 'webapps')){
+ OC_OCS::systemwebapps($format);
+
+ // quotaget
+ }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){
+ $user=$ex[$paracount-3];
+ OC_OCS::quotaget($format,$user);
+
+ // quotaset
+ }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){
+ $user=$ex[$paracount-3];
+ $quota = self::readData('post', 'quota', 'int');
+ OC_OCS::quotaset($format,$user,$quota);
+
+ // keygetpublic
+ }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){
+ $user=$ex[$paracount-3];
+ OC_OCS::publicKeyGet($format,$user);
+
+ // keygetprivate
+ }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){
+ $user=$ex[$paracount-3];
+ OC_OCS::privateKeyGet($format,$user);
+
+
+// add more calls here
+// please document all the call in the draft spec
+// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD
+
+// TODO:
+// users
+// groups
+// bookmarks
+// sharing
+// versioning
+// news (rss)
+
+
+
+ }else{
+ $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n";
+ $txt.=OC_OCS::getdebugoutput();
+ echo(OC_OCS::generatexml($format,'failed',999,$txt));
+ }
+ exit();
+ }
+
+ /**
+ * generated some debug information to make it easier to find faild API calls
+ * @return debug data string
+ */
+ private static function getDebugOutput() {
+ $txt='';
+ $txt.="debug output:\n";
+ if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n";
+ if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n";
+ if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n";
+ if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n";
+ return($txt);
+ }
+
+ /**
+ * checks if the user is authenticated
+ * checks the IP whitlist, apikeys and login/password combination
+ * if $forceuser is true and the authentication failed it returns an 401 http response.
+ * if $forceuser is false and authentification fails it returns an empty username string
+ * @param bool $forceuser
+ * @return username string
+ */
+ private static function checkPassword($forceuser=true) {
+ //valid user account ?
+ if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
+ if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
+
+ if(empty($authuser)) {
+ if($forceuser){
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }else{
+ $identifieduser='';
+ }
+ }else{
+ if(!OC_User::login($authuser,$authpw)){
+ if($forceuser){
+ header('WWW-Authenticate: Basic realm="your valid user account or api key"');
+ header('HTTP/1.0 401 Unauthorized');
+ exit;
+ }else{
+ $identifieduser='';
+ }
+ }else{
+ $identifieduser=$authuser;
+ }
+ }
+
+ return($identifieduser);
+ }
+
+
+ /**
+ * generates the xml or json response for the API call from an multidimenional data array.
+ * @param string $format
+ * @param string $status
+ * @param string $statuscode
+ * @param string $message
+ * @param array $data
+ * @param string $tag
+ * @param string $tagattribute
+ * @param int $dimension
+ * @param int $itemscount
+ * @param int $itemsperpage
+ * @return string xml/json
+ */
+ private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') {
+ if($format=='json') {
+ $json=array();
+ $json['status']=$status;
+ $json['statuscode']=$statuscode;
+ $json['message']=$message;
+ $json['totalitems']=$itemscount;
+ $json['itemsperpage']=$itemsperpage;
+ $json['data']=$data;
+ return(json_encode($json));
+ }else{
+ $txt='';
+ $writer = xmlwriter_open_memory();
+ xmlwriter_set_indent( $writer, 2 );
+ xmlwriter_start_document($writer );
+ xmlwriter_start_element($writer,'ocs');
+ xmlwriter_start_element($writer,'meta');
+ xmlwriter_write_element($writer,'status',$status);
+ xmlwriter_write_element($writer,'statuscode',$statuscode);
+ xmlwriter_write_element($writer,'message',$message);
+ if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount);
+ if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage);
+ xmlwriter_end_element($writer);
+ if($dimension=='0') {
+ // 0 dimensions
+ xmlwriter_write_element($writer,'data',$data);
+
+ }elseif($dimension=='1') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $key=>$entry) {
+ xmlwriter_write_element($writer,$key,$entry);
+ }
+ xmlwriter_end_element($writer);
+
+ }elseif($dimension=='2') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $entry) {
+ xmlwriter_start_element($writer,$tag);
+ if(!empty($tagattribute)) {
+ xmlwriter_write_attribute($writer,'details',$tagattribute);
+ }
+ foreach($entry as $key=>$value) {
+ if(is_array($value)){
+ foreach($value as $k=>$v) {
+ xmlwriter_write_element($writer,$k,$v);
+ }
+ } else {
+ xmlwriter_write_element($writer,$key,$value);
+ }
+ }
+ xmlwriter_end_element($writer);
+ }
+ xmlwriter_end_element($writer);
+
+ }elseif($dimension=='3') {
+ xmlwriter_start_element($writer,'data');
+ foreach($data as $entrykey=>$entry) {
+ xmlwriter_start_element($writer,$tag);
+ if(!empty($tagattribute)) {
+ xmlwriter_write_attribute($writer,'details',$tagattribute);
+ }
+ foreach($entry as $key=>$value) {
+ if(is_array($value)){
+ xmlwriter_start_element($writer,$entrykey);
+ foreach($value as $k=>$v) {
+ xmlwriter_write_element($writer,$k,$v);
+ }
+ xmlwriter_end_element($writer);
+ } else {
+ xmlwriter_write_element($writer,$key,$value);
+ }
+ }
+ xmlwriter_end_element($writer);
+ }
+ xmlwriter_end_element($writer);
+ }elseif($dimension=='dynamic') {
+ xmlwriter_start_element($writer,'data');
+ OC_OCS::toxml($writer,$data,'comment');
+ xmlwriter_end_element($writer);
+ }
+
+ xmlwriter_end_element($writer);
+
+ xmlwriter_end_document( $writer );
+ $txt.=xmlwriter_output_memory( $writer );
+ unset($writer);
+ return($txt);
+ }
+ }
+
+ public static function toXml($writer,$data,$node) {
+ foreach($data as $key => $value) {
+ if (is_numeric($key)) {
+ $key = $node;
+ }
+ if (is_array($value)){
+ xmlwriter_start_element($writer,$key);
+ OC_OCS::toxml($writer,$value,$node);
+ xmlwriter_end_element($writer);
+ }else{
+ xmlwriter_write_element($writer,$key,$value);
+ }
+ }
+ }
+
+
+
+
+ /**
+ * return the config data of this server
+ * @param string $format
+ * @return string xml/json
+ */
+ private static function apiConfig($format) {
+ $user=OC_OCS::checkpassword(false);
+ $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).'';
+
+ $xml['version']='1.7';
+ $xml['website']='ownCloud';
+ $xml['host']=OCP\Util::getServerHost();
+ $xml['contact']='';
+ $xml['ssl']='false';
+ echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1));
+ }
+
+
+ /**
+ * check if the provided login/apikey/password is valid
+ * @param string $format
+ * @param string $login
+ * @param string $passwd
+ * @return string xml/json
+ */
+ private static function personCheck($format,$login,$passwd) {
+ if($login<>''){
+ if(OC_User::login($login,$passwd)){
+ $xml['person']['personid']=$login;
+ echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2));
+ }else{
+ echo(OC_OCS::generatexml($format,'failed',102,'login not valid'));
+ }
+ }else{
+ echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields'));
+ }
+ }
+
+
+
+ // ACTIVITY API #############################################
+
+ /**
+ * get my activities
+ * @param string $format
+ * @param string $page
+ * @param string $pagesize
+ * @return string xml/json
+ */
+ private static function activityGet($format,$page,$pagesize) {
+ $user=OC_OCS::checkpassword();
+
+ //TODO
+
+ $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize);
+ echo($txt);
+ }
+
+ /**
+ * submit a activity
+ * @param string $format
+ * @param string $message
+ * @return string xml/json
+ */
+ private static function activityPut($format,$message) {
+ // not implemented in ownCloud
+ $user=OC_OCS::checkpassword();
+ echo(OC_OCS::generatexml($format,'ok',100,''));
+ }
+
+ // PRIVATEDATA API #############################################
+
+ /**
+ * get private data and create the xml for ocs
+ * @param string $format
+ * @param string $app
+ * @param string $key
+ * @return string xml/json
+ */
+ private static function privateDataGet($format,$app="",$key="") {
+ $user=OC_OCS::checkpassword();
+ $result=OC_OCS::getData($user,$app,$key);
+ $xml=array();
+ foreach($result as $i=>$log) {
+ $xml[$i]['key']=$log['key'];
+ $xml[$i]['app']=$log['app'];
+ $xml[$i]['value']=$log['value'];
+ }
+
+
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it
+ echo($txt);
+ }
+
+ /**
+ * set private data referenced by $key to $value and generate the xml for ocs
+ * @param string $format
+ * @param string $app
+ * @param string $key
+ * @param string $value
+ * @return string xml/json
+ */
private static function privateDataSet($format, $app, $key, $value) {
$user=OC_OCS::checkpassword();
if(OC_OCS::setData($user,$app,$key,$value)){
@@ -525,4 +555,134 @@ class OC_OCS {
public static function deleteData($user, $app, $key) {
return OC_Preferences::deleteKey($user,$app,$key);
}
+
+
+ // CLOUD API #############################################
+
+ /**
+ * get a list of installed web apps
+ * @param string $format
+ * @return string xml/json
+ */
+ private static function systemWebApps($format) {
+ $login=OC_OCS::checkpassword();
+ $apps=OC_App::getEnabledApps();
+ $values=array();
+ foreach($apps as $app) {
+ $info=OC_App::getAppInfo($app);
+ if(isset($info['standalone'])) {
+ $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
+ $values[]=$newvalue;
+ }
+
+ }
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0);
+ echo($txt);
+
+ }
+
+
+ /**
+ * get the quota of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function quotaGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $user_dir = '/'.$user.'/files';
+ OC_Filesystem::init($user_dir);
+ $rootInfo=OC_FileCache::get('');
+ $sharedInfo=OC_FileCache::get('/Shared');
+ $used=$rootInfo['size']-$sharedInfo['size'];
+ $free=OC_Filesystem::free_space();
+ $total=$free+$used;
+ if($total==0) $total=1; // prevent division by zero
+ $relative=round(($used/$total)*10000)/100;
+
+ $xml=array();
+ $xml['quota']=$total;
+ $xml['free']=$free;
+ $xml['used']=$used;
+ $xml['relative']=$relative;
+
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+ /**
+ * set the quota of a user
+ * @param string $format
+ * @param string $user
+ * @param string $quota
+ * @return string xml/json
+ */
+ private static function quotaSet($format,$user,$quota) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin')) {
+
+ // todo
+ // not yet implemented
+ // add logic here
+ error_log('OCS call: user:'.$user.' quota:'.$quota);
+
+ $xml=array();
+ $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0);
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+ /**
+ * get the public key of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function publicKeyGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $txt='this is the public key of '.$user;
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }
+
+ /**
+ * get the private key of a user
+ * @param string $format
+ * @param string $user
+ * @return string xml/json
+ */
+ private static function privateKeyGet($format,$user) {
+ $login=OC_OCS::checkpassword();
+ if(OC_Group::inGroup($login, 'admin') or ($login==$user)) {
+
+ if(OC_User::userExists($user)){
+ // calculate the disc space
+ $txt='this is the private key of '.$user;
+ echo($txt);
+ }else{
+ echo self::generateXml('', 'fail', 300, 'User does not exist');
+ }
+ }else{
+ echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.');
+ }
+ }
+
+
}
diff --git a/lib/public/app.php b/lib/public/app.php
index 28411933beb..5689f53ffb2 100644
--- a/lib/public/app.php
+++ b/lib/public/app.php
@@ -35,6 +35,21 @@ namespace OCP;
*/
class App {
/**
+ * @brief Makes owncloud aware of this app
+ * @brief This call is deprecated and not necessary to use.
+ * @param $data array with all information
+ * @returns true/false
+ *
+ * @deprecated this method is deprecated
+ * Do not call it anymore
+ * It'll remain in our public API for compatibility reasons
+ *
+ */
+ public static function register( $data ){
+ return \OC_App::register( $data );
+ }
+
+ /**
* @brief adds an entry to the navigation
* @param $data array containing the data
* @returns true/false
diff --git a/lib/public/groupinterface.php b/lib/public/groupinterface.php
new file mode 100644
index 00000000000..97833028118
--- /dev/null
+++ b/lib/public/groupinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * Group Class.
+ *
+ */
+
+namespace OCP;
+
+interface GroupInterface extends \OC_Group_Interface {} \ No newline at end of file
diff --git a/lib/public/userinterface.php b/lib/public/userinterface.php
new file mode 100644
index 00000000000..b73a8f8d8b0
--- /dev/null
+++ b/lib/public/userinterface.php
@@ -0,0 +1,31 @@
+<?php
+/**
+* ownCloud
+*
+* @author Arthur Schiwon
+* @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+*
+* This library is free software; you can redistribute it and/or
+* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+* License as published by the Free Software Foundation; either
+* version 3 of the License, or any later version.
+*
+* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+*
+* You should have received a copy of the GNU Affero General Public
+* License along with this library. If not, see <http://www.gnu.org/licenses/>.
+*
+*/
+
+/**
+ * Public interface of ownCloud for apps to use.
+ * User Class.
+ *
+ */
+
+namespace OCP;
+
+interface UserInterface extends \OC_User_Interface {} \ No newline at end of file
diff --git a/lib/public/util.php b/lib/public/util.php
index 43f9e3cee5d..75ca29f7129 100644
--- a/lib/public/util.php
+++ b/lib/public/util.php
@@ -320,4 +320,15 @@ class Util {
public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) {
return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count));
}
+
+ /**
+ * @brief performs a search in a nested array
+ * @param haystack the array to be searched
+ * @param needle the search string
+ * @param $index optional, only search this key name
+ * @return the key of the matching field, otherwise false
+ */
+ public static function recursiveArraySearch($haystack, $needle, $index = null) {
+ return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index));
+ }
}
diff --git a/lib/user.php b/lib/user.php
index 356be4decf9..e3c9c23effa 100644
--- a/lib/user.php
+++ b/lib/user.php
@@ -21,7 +21,7 @@
*/
/**
- * This class provides wrapper methods for user management. Multiple backends are
+ * This class provides wrapper methods for user management. Multiple backends are
* supported. User management operations are delegated to the configured backend for
* execution.
*
@@ -83,7 +83,7 @@ class OC_User {
* Set the User Authentication Module
*/
public static function useBackend( $backend = 'database' ){
- if($backend instanceof OC_User_Backend){
+ if($backend instanceof OC_User_Interface){
self::$_usedBackends[get_class($backend)]=$backend;
}else{
// You'll never know what happens
@@ -104,11 +104,17 @@ class OC_User {
break;
}
}
-
true;
}
/**
+ * remove all used backends
+ */
+ public static function clearBackends(){
+ self::$_usedBackends=array();
+ }
+
+ /**
* @brief Create a new user
* @param $uid The username of the user to create
* @param $password The password of the new user
diff --git a/lib/user/backend.php b/lib/user/backend.php
index be068a63ce0..daa942d261c 100644
--- a/lib/user/backend.php
+++ b/lib/user/backend.php
@@ -42,7 +42,7 @@ define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100);
*
* Subclass this for your own backends, and see OC_User_Example for descriptions
*/
-abstract class OC_User_Backend {
+abstract class OC_User_Backend implements OC_User_Interface {
protected $possibleActions = array(
OC_USER_BACKEND_CREATE_USER => 'createUser',
diff --git a/lib/user/interface.php b/lib/user/interface.php
new file mode 100644
index 00000000000..dc3685dc20d
--- /dev/null
+++ b/lib/user/interface.php
@@ -0,0 +1,60 @@
+<?php
+
+/**
+ * ownCloud - user interface
+ *
+ * @author Arthur Schiwon
+ * @copyright 2012 Arthur Schiwon blizzz@owncloud.org
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or any later version.
+ *
+ * This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ */
+
+interface OC_User_Interface {
+
+ /**
+ * @brief Check if backend implements actions
+ * @param $actions bitwise-or'ed actions
+ * @returns boolean
+ *
+ * Returns the supported actions as int to be
+ * compared with OC_USER_BACKEND_CREATE_USER etc.
+ */
+ public function implementsActions($actions);
+
+ /**
+ * @brief delete a user
+ * @param $uid The username of the user to delete
+ * @returns true/false
+ *
+ * Deletes a user
+ */
+ public function deleteUser($uid);
+
+ /**
+ * @brief Get a list of all users
+ * @returns array with all uids
+ *
+ * Get a list of all users.
+ */
+ public function getUsers();
+
+ /**
+ * @brief check if a user exists
+ * @param string $uid the username
+ * @return boolean
+ */
+ public function userExists($uid);
+
+} \ No newline at end of file
diff --git a/lib/util.php b/lib/util.php
index f1a87742168..6e62ed9bf58 100755
--- a/lib/util.php
+++ b/lib/util.php
@@ -77,13 +77,13 @@ class OC_Util {
return '5 pre alpha';
}
- /**
- * get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
- * @return string
- */
- public static function getEditionString(){
- return '';
- }
+ /**
+ * get the current installed edition of ownCloud. There is the community edition that just returns an empty string and the enterprise edition that returns "Enterprise".
+ * @return string
+ */
+ public static function getEditionString(){
+ return '';
+ }
/**
* add a javascript file
@@ -131,12 +131,12 @@ class OC_Util {
self::$headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text);
}
- /**
- * formats a timestamp in the "right" way
- *
- * @param int timestamp $timestamp
- * @param bool dateOnly option to ommit time from the result
- */
+ /**
+ * formats a timestamp in the "right" way
+ *
+ * @param int timestamp $timestamp
+ * @param bool dateOnly option to ommit time from the result
+ */
public static function formatDate( $timestamp,$dateOnly=false){
if(isset($_SESSION['timezone'])){//adjust to clients timezone if we know it
$systemTimeZone = intval(date('O'));
@@ -455,26 +455,25 @@ class OC_Util {
}
- /**
- * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
- */
- public static function ishtaccessworking() {
-
+ /**
+ * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http
+ */
+ public static function ishtaccessworking() {
// testdata
$filename='/htaccesstest.txt';
$testcontent='testcontent';
// creating a test file
- $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
- $fp = @fopen($testfile, 'w');
- @fwrite($fp, $testcontent);
- @fclose($fp);
+ $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename;
+ $fp = @fopen($testfile, 'w');
+ @fwrite($fp, $testcontent);
+ @fclose($fp);
// accessing the file via http
- $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
- $fp = @fopen($url, 'r');
- $content=@fread($fp, 2048);
- @fclose($fp);
+ $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename;
+ $fp = @fopen($url, 'r');
+ $content=@fread($fp, 2048);
+ @fclose($fp);
// cleanup
@unlink($testfile);
@@ -484,13 +483,7 @@ class OC_Util {
return(false);
}else{
return(true);
-
}
-
- }
-
-
-
-
+ }
}
diff --git a/ocs/providers.php b/ocs/providers.php
index f9cafd20b01..cc6de32266b 100644
--- a/ocs/providers.php
+++ b/ocs/providers.php
@@ -35,7 +35,9 @@ echo('
<termsofuse></termsofuse>
<register></register>
<services>
- <activity ocsversion="1.5" />
+ <config ocsversion="1.7" />
+ <activity ocsversion="1.7" />
+ <cloud ocsversion="1.7" />
</services>
</provider>
</providers>
diff --git a/remote.php b/remote.php
index 8461eea19ad..8dc4df1bd23 100644
--- a/remote.php
+++ b/remote.php
@@ -34,7 +34,7 @@ switch ($app) {
default:
OC_Util::checkAppEnabled($app);
OC_App::loadApp($app);
- $file = OC_App::getAppPath($app) .'/'. $parts[1];
+ $file = '/' . OC_App::getAppPath($app) .'/'. $parts[1];
break;
}
$baseuri = OC::$WEBROOT . '/remote.php/'.$service.'/';
diff --git a/settings/l10n/es.php b/settings/l10n/es.php
index c8ddb412ecf..305728d3dc7 100644
--- a/settings/l10n/es.php
+++ b/settings/l10n/es.php
@@ -1,12 +1,19 @@
<?php $TRANSLATIONS = array(
+"Email saved" => "Correo salvado",
+"Invalid email" => "Correo Incorrecto",
"OpenID Changed" => "OpenID cambiado",
"Invalid request" => "Solicitud no válida",
"Language changed" => "Idioma cambiado",
+"Disable" => "Desactivar",
+"Enable" => "Activar",
+"Saving..." => "Salvando..",
"__language_name__" => "Castellano",
+"Security Warning" => "Advertencia de seguridad",
"Log" => "Registro",
"More" => "Más",
"Add your App" => "Añade tu aplicación",
"Select an App" => "Seleccionar una aplicación",
+"See application page at apps.owncloud.com" => "Revisa la web de apps apps.owncloud.com",
"-licensed" => "-autorizado",
"by" => "por",
"Documentation" => "Documentación",
diff --git a/settings/l10n/it.php b/settings/l10n/it.php
index a4b255546a1..ca138cf8c18 100644
--- a/settings/l10n/it.php
+++ b/settings/l10n/it.php
@@ -1,12 +1,19 @@
<?php $TRANSLATIONS = array(
+"Email saved" => "Email salvata",
+"Invalid email" => "Email non valida",
"OpenID Changed" => "OpenID modificato",
"Invalid request" => "Richiesta non valida",
"Language changed" => "Lingua modificata",
+"Disable" => "Disabilita",
+"Enable" => "Abilita",
+"Saving..." => "Salvataggio in corso...",
"__language_name__" => "Italiano",
+"Security Warning" => "Avviso di sicurezza",
"Log" => "Registro",
"More" => "Altro",
"Add your App" => "Aggiungi la tua applicazione",
"Select an App" => "Seleziona un'applicazione",
+"See application page at apps.owncloud.com" => "Vedere la pagina dell'applicazione su apps.owncloud.com",
"-licensed" => "-rilasciato",
"by" => "da",
"Documentation" => "Documentazione",
diff --git a/settings/l10n/vi.php b/settings/l10n/vi.php
new file mode 100644
index 00000000000..41e4441b1cb
--- /dev/null
+++ b/settings/l10n/vi.php
@@ -0,0 +1,48 @@
+<?php $TRANSLATIONS = array(
+"Email saved" => "Lưu email",
+"Invalid email" => "Email không hợp lệ",
+"OpenID Changed" => "Đổi OpenID",
+"Invalid request" => "Yêu cầu không hợp lệ",
+"Language changed" => "Ngôn ngữ đã được thay đổi",
+"Disable" => "Vô hiệu",
+"Enable" => "Cho phép",
+"Saving..." => "Đang tiến hành lưu ...",
+"__language_name__" => "__Ngôn ngữ___",
+"Log" => "Log",
+"More" => "nhiều hơn",
+"Add your App" => "Thêm ứng dụng của bạn",
+"Select an App" => "Chọn một ứng dụng",
+"See application page at apps.owncloud.com" => "Xem ứng dụng tại apps.owncloud.com",
+"-licensed" => "Giấy phép đã được cấp",
+"by" => "bởi",
+"Documentation" => "Tài liệu",
+"Managing Big Files" => "Quản lý tập tin lớn",
+"Ask a question" => "Đặt câu hỏi",
+"Problems connecting to help database." => "Vấn đề kết nối đến cơ sở dữ liệu.",
+"Go there manually." => "Đến bằng thủ công",
+"Answer" => "trả lời",
+"You use" => "Bạn sử dụng",
+"of the available" => "có sẵn",
+"Desktop and Mobile Syncing Clients" => "Đồng bộ dữ liệu",
+"Download" => "Tải về",
+"Your password got changed" => "Mật khẩu đã được thay đổi",
+"Unable to change your password" => "Không thể đổi mật khẩu",
+"Current password" => "Mật khẩu cũ",
+"New password" => "Mật khẩu mới ",
+"show" => "Hiện",
+"Change password" => "Đổi mật khẩu",
+"Email" => "Email",
+"Your email address" => "Email của bạn",
+"Fill in an email address to enable password recovery" => "Nhập địa chỉ email của bạn để khôi phục lại mật khẩu",
+"Language" => "Ngôn ngữ",
+"Help translate" => "Dịch ",
+"use this address to connect to your ownCloud in your file manager" => "sử dụng địa chỉ này để kết nối với ownCloud của bạn trong quản lý tập tin ",
+"Name" => "Tên",
+"Password" => "Mật khẩu",
+"Groups" => "Nhóm",
+"Create" => "Tạo",
+"Default Quota" => "Hạn ngạch mặt định",
+"Other" => "Khác",
+"Quota" => "Hạn ngạch",
+"Delete" => "Xóa"
+);
diff --git a/tests/lib/cache.php b/tests/lib/cache.php
index bb5cfc6ee19..511999be956 100644
--- a/tests/lib/cache.php
+++ b/tests/lib/cache.php
@@ -42,6 +42,27 @@ abstract class Test_Cache extends UnitTestCase {
$this->assertNull($this->instance->get('not_set'),'Unset value not equal to null');
$this->assertTrue($this->instance->remove('value1'));
+ $this->assertFalse($this->instance->hasKey('value1'));
+ }
+
+ function testClear(){
+ $value='ipsum lorum';
+ $this->instance->set('1_value1',$value);
+ $this->instance->set('1_value2',$value);
+ $this->instance->set('2_value1',$value);
+ $this->instance->set('3_value1',$value);
+
+ $this->assertTrue($this->instance->clear('1_'));
+ $this->assertFalse($this->instance->hasKey('1_value1'));
+ $this->assertFalse($this->instance->hasKey('1_value2'));
+ $this->assertTrue($this->instance->hasKey('2_value1'));
+ $this->assertTrue($this->instance->hasKey('3_value1'));
+
+ $this->assertTrue($this->instance->clear());
+ $this->assertFalse($this->instance->hasKey('1_value1'));
+ $this->assertFalse($this->instance->hasKey('1_value2'));
+ $this->assertFalse($this->instance->hasKey('2_value1'));
+ $this->assertFalse($this->instance->hasKey('3_value1'));
}
function testTTL(){
diff --git a/tests/lib/cache/file.php b/tests/lib/cache/file.php
index c33c513fcff..28778efb68c 100644
--- a/tests/lib/cache/file.php
+++ b/tests/lib/cache/file.php
@@ -21,8 +21,10 @@
*/
class Test_Cache_File extends Test_Cache {
+ private $user;
+
function skip() {
- $this->skipUnless(OC_User::isLoggedIn());
+ //$this->skipUnless(OC_User::isLoggedIn());
}
public function setUp(){
@@ -39,10 +41,23 @@ class Test_Cache_File extends Test_Cache {
OC_Filesystem::clearMounts();
OC_Filesystem::mount('OC_Filestorage_Temporary',array(),'/');
+ OC_User::clearBackends();
+ OC_User::useBackend(new OC_User_Dummy());
+
+ //login
+ OC_User::createUser('test', 'test');
+
+ $this->user=OC_User::getUser();
+ OC_User::setUserId('test');
+
//set up the users dir
$rootView=new OC_FilesystemView('');
- $rootView->mkdir('/'.OC_User::getUser());
+ $rootView->mkdir('/test');
$this->instance=new OC_Cache_File();
}
+
+ public function tearDown(){
+ OC_User::setUserId($this->user);
+ }
}
diff --git a/webapps.php b/webapps.php
deleted file mode 100644
index 82e677a51c7..00000000000
--- a/webapps.php
+++ /dev/null
@@ -1,54 +0,0 @@
-<?php
-
-/**
-* ownCloud status page. usefull if you want to check from the outside if an owncloud installation exists
-*
-* @author Frank Karlitschek
-* @copyright 2012 Frank Karlitschek frank@owncloud.org
-*
-* This library is free software; you can redistribute it and/or
-* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE
-* License as published by the Free Software Foundation; either
-* version 3 of the License, or any later version.
-*
-* This library 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 AFFERO GENERAL PUBLIC LICENSE for more details.
-*
-* You should have received a copy of the GNU Affero General Public
-* License along with this library. If not, see <http://www.gnu.org/licenses/>.
-*
-*/
-
-$RUNTIME_NOAPPS = TRUE; //no apps, yet
-
-require_once('lib/base.php');
-
-
-//valid user account
-if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser='';
-if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw='';
-
-if(!OC_User::login($authuser,$authpw)){
- header('WWW-Authenticate: Basic realm="your valid user account"');
- header('HTTP/1.0 401 Unauthorized');
- exit;
-}else{
-
- $apps=OC_App::getEnabledApps();
- $values=array();
- foreach($apps as $app) {
- $info=OC_App::getAppInfo($app);
- if(isset($info['standalone'])) {
- $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>'');
- $values[]=$newvalue;
- }
-
- }
-
- echo(json_encode($values));
- exit;
-
-
-}