summaryrefslogtreecommitdiff
path: root/plugin.library.node.editor
diff options
context:
space:
mode:
authorronie <ronie@users.noreply.github.com>2016-04-30 22:27:23 +0200
committerronie <ronie@users.noreply.github.com>2016-04-30 22:27:23 +0200
commit503928799dd20978d236e412156c51ec8bb3abb1 (patch)
treee15a0ce2e8678a4e8fa3b0bcec86d575cbc381ca /plugin.library.node.editor
parenta29373b0db217fb0aed8642973bebf1d6f9c7ae6 (diff)
plugin.library.node.editor 1.0.1
Diffstat (limited to 'plugin.library.node.editor')
-rwxr-xr-xplugin.library.node.editor/LICENSE.txt339
-rwxr-xr-xplugin.library.node.editor/addon.py816
-rw-r--r--plugin.library.node.editor/addon.xml43
-rw-r--r--plugin.library.node.editor/changelog.txt18
-rwxr-xr-xplugin.library.node.editor/icon.pngbin0 -> 10776 bytes
-rw-r--r--plugin.library.node.editor/resources/language/Afrikaans/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Albanian/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Amharic/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Arabic/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Armenian/strings.po29
-rw-r--r--plugin.library.node.editor/resources/language/Asturian/strings.po21
-rw-r--r--plugin.library.node.editor/resources/language/Azerbaijani/strings.po29
-rw-r--r--plugin.library.node.editor/resources/language/Basque/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Belarusian/strings.po61
-rw-r--r--plugin.library.node.editor/resources/language/Bosnian/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Bulgarian/strings.po173
-rw-r--r--plugin.library.node.editor/resources/language/Burmese/strings.po37
-rw-r--r--plugin.library.node.editor/resources/language/Catalan/strings.po61
-rw-r--r--plugin.library.node.editor/resources/language/Chinese (Simple)/strings.po81
-rw-r--r--plugin.library.node.editor/resources/language/Chinese (Traditional)/strings.po53
-rw-r--r--plugin.library.node.editor/resources/language/Croatian/strings.po69
-rw-r--r--plugin.library.node.editor/resources/language/Czech/strings.po65
-rw-r--r--plugin.library.node.editor/resources/language/Danish/strings.po65
-rw-r--r--plugin.library.node.editor/resources/language/Dutch/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/English (Australia)/strings.po65
-rw-r--r--plugin.library.node.editor/resources/language/English (New Zealand)/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/English (US)/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/English/strings.po332
-rw-r--r--plugin.library.node.editor/resources/language/Esperanto/strings.po25
-rw-r--r--plugin.library.node.editor/resources/language/Estonian/strings.po49
-rw-r--r--plugin.library.node.editor/resources/language/Faroese/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Finnish/strings.po57
-rw-r--r--plugin.library.node.editor/resources/language/French (Canada)/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/French/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Galician/strings.po177
-rw-r--r--plugin.library.node.editor/resources/language/German/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Greek/strings.po121
-rw-r--r--plugin.library.node.editor/resources/language/Haitian (Haitian Creole)/strings.po21
-rw-r--r--plugin.library.node.editor/resources/language/Hebrew/strings.po157
-rw-r--r--plugin.library.node.editor/resources/language/Hindi (Devanagiri)/strings.po29
-rw-r--r--plugin.library.node.editor/resources/language/Hungarian/strings.po81
-rw-r--r--plugin.library.node.editor/resources/language/Icelandic/strings.po61
-rw-r--r--plugin.library.node.editor/resources/language/Indonesian/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Italian/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Japanese/strings.po53
-rw-r--r--plugin.library.node.editor/resources/language/Korean/strings.po153
-rw-r--r--plugin.library.node.editor/resources/language/Latvian/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Lithuanian/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Macedonian/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Malay/strings.po69
-rw-r--r--plugin.library.node.editor/resources/language/Malayalam/strings.po21
-rw-r--r--plugin.library.node.editor/resources/language/Maltese/strings.po29
-rw-r--r--plugin.library.node.editor/resources/language/Mongolian (Mongolia)/strings.po25
-rw-r--r--plugin.library.node.editor/resources/language/Norwegian/strings.po65
-rw-r--r--plugin.library.node.editor/resources/language/Persian (Iran)/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Persian/strings.po21
-rw-r--r--plugin.library.node.editor/resources/language/Polish/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Portuguese (Brazil)/strings.po213
-rw-r--r--plugin.library.node.editor/resources/language/Portuguese/strings.po73
-rw-r--r--plugin.library.node.editor/resources/language/Romanian/strings.po177
-rw-r--r--plugin.library.node.editor/resources/language/Russian/strings.po81
-rw-r--r--plugin.library.node.editor/resources/language/Serbian (Cyrillic)/strings.po37
-rw-r--r--plugin.library.node.editor/resources/language/Serbian/strings.po41
-rw-r--r--plugin.library.node.editor/resources/language/Slovak/strings.po53
-rw-r--r--plugin.library.node.editor/resources/language/Slovenian/strings.po61
-rw-r--r--plugin.library.node.editor/resources/language/Spanish (Argentina)/strings.po57
-rw-r--r--plugin.library.node.editor/resources/language/Spanish (Mexico)/strings.po57
-rw-r--r--plugin.library.node.editor/resources/language/Spanish/strings.po81
-rw-r--r--plugin.library.node.editor/resources/language/Swedish/strings.po89
-rw-r--r--plugin.library.node.editor/resources/language/Tamil (India)/strings.po45
-rw-r--r--plugin.library.node.editor/resources/language/Thai/strings.po57
-rw-r--r--plugin.library.node.editor/resources/language/Turkish/strings.po77
-rw-r--r--plugin.library.node.editor/resources/language/Ukrainian/strings.po53
-rw-r--r--plugin.library.node.editor/resources/language/Uzbek/strings.po33
-rw-r--r--plugin.library.node.editor/resources/language/Vietnamese/strings.po37
-rw-r--r--plugin.library.node.editor/resources/language/Welsh/strings.po49
-rw-r--r--plugin.library.node.editor/resources/language/Western Frisian/strings.po29
-rwxr-xr-xplugin.library.node.editor/resources/lib/orderby.py209
-rw-r--r--plugin.library.node.editor/resources/lib/pathrules.py391
-rw-r--r--plugin.library.node.editor/resources/lib/pluginBrowser.py65
-rwxr-xr-xplugin.library.node.editor/resources/lib/rules.py1107
-rwxr-xr-xplugin.library.node.editor/resources/lib/viewattrib.py367
-rw-r--r--plugin.library.node.editor/resources/musicrules.xml323
-rwxr-xr-xplugin.library.node.editor/resources/videorules.xml529
84 files changed, 10350 insertions, 0 deletions
diff --git a/plugin.library.node.editor/LICENSE.txt b/plugin.library.node.editor/LICENSE.txt
new file mode 100755
index 0000000..d159169
--- /dev/null
+++ b/plugin.library.node.editor/LICENSE.txt
@@ -0,0 +1,339 @@
+ 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.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License along
+ with this program; if not, write to the Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Lesser General
+Public License instead of this License.
diff --git a/plugin.library.node.editor/addon.py b/plugin.library.node.editor/addon.py
new file mode 100755
index 0000000..43f1004
--- /dev/null
+++ b/plugin.library.node.editor/addon.py
@@ -0,0 +1,816 @@
+# coding=utf-8
+import os, sys, shutil, unicodedata, re, types
+from htmlentitydefs import name2codepoint
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
+import xml.etree.ElementTree as xmltree
+import urllib
+from unidecode import unidecode
+from urlparse import parse_qs
+from traceback import print_exc
+import json
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+ADDONVERSION = ADDON.getAddonInfo('version')
+LANGUAGE = ADDON.getLocalizedString
+CWD = ADDON.getAddonInfo('path').decode("utf-8")
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+RESOURCE = xbmc.translatePath( os.path.join( CWD, 'resources', 'lib' ) ).decode("utf-8")
+DATAPATH = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')).decode('utf-8')
+
+sys.path.append(RESOURCE)
+
+# character entity reference
+CHAR_ENTITY_REXP = re.compile('&(%s);' % '|'.join(name2codepoint))
+
+# decimal character reference
+DECIMAL_REXP = re.compile('&#(\d+);')
+
+# hexadecimal character reference
+HEX_REXP = re.compile('&#x([\da-fA-F]+);')
+
+REPLACE1_REXP = re.compile(r'[\']+')
+REPLACE2_REXP = re.compile(r'[^-a-z0-9]+')
+REMOVE_REXP = re.compile('-{2,}')
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+class Main:
+ # MAIN ENTRY POINT
+ def __init__(self):
+ self._parse_argv()
+ # If there are no custom library nodes in the profile directory, copy them from the Kodi install
+ targetDir = os.path.join( xbmc.translatePath( "special://profile".decode('utf-8') ), "library", ltype )
+ if True:
+ if not os.path.exists( targetDir ):
+ xbmcvfs.mkdirs( targetDir )
+ originDir = os.path.join( xbmc.translatePath( "special://xbmc".decode( "utf-8" ) ), "system", "library", ltype )
+ dirs, files = xbmcvfs.listdir( originDir )
+ self.copyNode( dirs, files, targetDir, originDir )
+ else:
+ xbmcgui.Dialog().ok(ADDONNAME, LANGUAGE( 30400 ) )
+ print_exc
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ return
+ # Create data if not exists
+ if not os.path.exists(DATAPATH):
+ xbmcvfs.mkdir(DATAPATH)
+ if "type" in self.PARAMS:
+ # We're performing a specific action
+ if self.PARAMS[ "type" ] == "delete":
+ message = LANGUAGE( 30401 )
+ if self.PARAMS[ "actionPath" ] == targetDir:
+ # Ask the user is they want to reset all nodes
+ message = LANGUAGE( 30402 )
+ result = xbmcgui.Dialog().yesno(ADDONNAME, message )
+ if result:
+ if self.PARAMS[ "actionPath" ].endswith( ".xml" ):
+ # Delete single file
+ xbmcvfs.delete( self.PARAMS[ "actionPath" ] )
+ else:
+ # Delete folder
+ RULE.deleteAllNodeRules( self.PARAMS[ "actionPath" ] )
+ shutil.rmtree( self.PARAMS[ "actionPath" ] )
+ else:
+ return
+ elif self.PARAMS[ "type" ] == "deletenode":
+ result = xbmcgui.Dialog().yesno(ADDONNAME, LANGUAGE( 30403 ) )
+ if result:
+ self.changeViewElement( self.PARAMS[ "actionPath" ], self.PARAMS[ "node" ], "" )
+ elif self.PARAMS[ "type" ] == "editlabel":
+ if self.PARAMS[ "label" ].isdigit():
+ label = xbmc.getLocalizedString( int( self.PARAMS[ "label" ] ) )
+ else:
+ label = self.PARAMS[ "label" ]
+ # Get new label from keyboard dialog
+ keyboard = xbmc.Keyboard( label, LANGUAGE( 30300 ), False )
+ keyboard.doModal()
+ if ( keyboard.isConfirmed() ):
+ newlabel = keyboard.getText().decode( "utf-8" )
+ if newlabel != "" and newlabel != label:
+ # We've got a new label, update the xml file
+ self.changeViewElement( self.PARAMS[ "actionPath" ], "label", newlabel )
+ else:
+ return
+ elif self.PARAMS[ "type" ] == "editvisibility":
+ currentVisibility = self.getRootAttrib( self.PARAMS[ "actionPath" ], "visible" )
+ # Get new visibility from keyboard dialog
+ keyboard = xbmc.Keyboard( currentVisibility, LANGUAGE( 30301 ), False )
+ keyboard.doModal()
+ if ( keyboard.isConfirmed() ):
+ newVisibility = keyboard.getText()
+ if newVisibility != currentVisibility:
+ # We've got a new label, update the xml file
+ self.changeRootAttrib( self.PARAMS[ "actionPath" ], "visible", newVisibility )
+ else:
+ return
+ elif self.PARAMS[ "type" ] == "editorder":
+ currentOrder = self.getRootAttrib( self.PARAMS[ "actionPath" ], "order" )
+ # Get new label from keyboard dialog
+ neworder = xbmcgui.Dialog().numeric( 0, LANGUAGE( 30302 ), currentOrder )
+ if neworder != "" and neworder != currentOrder:
+ # We've got a new label, update the xml file
+ self.changeRootAttrib( self.PARAMS[ "actionPath" ], "order", neworder )
+ elif self.PARAMS[ "type" ] == "newView":
+ # Get new view name from keyboard dialog
+ keyboard = xbmc.Keyboard( "", LANGUAGE( 30316 ), False )
+ keyboard.doModal()
+ if ( keyboard.isConfirmed() ):
+ newView = keyboard.getText().decode( "utf-8" )
+ if newView != "":
+ # Ensure filename is unique
+ filename = self.slugify( newView.lower().replace( " ", "" ) )
+ if os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], filename + ".xml" ) ):
+ count = 0
+ while os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], filename + "-" + str( count ) + ".xml" ) ):
+ count += 1
+ filename = filename + "-" + str( count )
+ # Create a new xml file
+ tree = xmltree.ElementTree( xmltree.Element( "node" ) )
+ root = tree.getroot()
+ subtree = xmltree.SubElement( root, "label" ).text = newView
+ # Add any node rules
+ RULE.addAllNodeRules( self.PARAMS[ "actionPath" ], root )
+ # Write the xml file
+ self.indent( root )
+ tree.write( os.path.join( self.PARAMS[ "actionPath" ], filename + ".xml" ), encoding="UTF-8" )
+ else:
+ return
+ elif self.PARAMS[ "type" ] == "newNode":
+ # Get new node name from the keyboard dialog
+ keyboard = xbmc.Keyboard( "", LANGUAGE( 30303 ), False )
+ keyboard.doModal()
+ if ( keyboard.isConfirmed() ):
+ newNode = keyboard.getText().decode( "utf8" )
+ if newNode == "":
+ return
+ # Ensure foldername is unique
+ foldername = self.slugify( newNode.lower().replace( " ", "" ) )
+ if os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], foldername + os.pathsep ) ):
+ count = 0
+ while os.path.exists( os.path.join( self.PARAMS[ "actionPath" ], foldername + "-" + str( count ) + os.pathsep ) ):
+ count += 1
+ foldername = foldername + "-" + str( count )
+ foldername = os.path.join( self.PARAMS[ "actionPath" ], foldername )
+ # Create new node folder
+ xbmcvfs.mkdir( foldername )
+ # Create a new xml file
+ tree = xmltree.ElementTree( xmltree.Element( "node" ) )
+ root = tree.getroot()
+ subtree = xmltree.SubElement( root, "label" ).text = newNode
+ # Ask user if they want to import defaults
+ if ltype == "video":
+ defaultNames = [ xbmc.getLocalizedString( 231 ), xbmc.getLocalizedString( 342 ), xbmc.getLocalizedString( 20343 ), xbmc.getLocalizedString( 20389 ) ]
+ defaultValues = [ "", "movies", "tvshows", "musicvideos" ]
+ selected = xbmcgui.Dialog().select( LANGUAGE( 30304 ), defaultNames )
+ else:
+ selected = 0
+ # If the user selected some defaults...
+ if selected != -1 and selected != 0:
+ try:
+ # Copy those defaults across
+ originDir = os.path.join( xbmc.translatePath( "special://xbmc".decode( "utf-8" ) ), "system", "library", ltype, defaultValues[ selected ] )
+ dirs, files = xbmcvfs.listdir( originDir )
+ for file in files:
+ if file != "index.xml":
+ xbmcvfs.copy( os.path.join( originDir, file), os.path.join( foldername, file ) )
+ # Open index.xml and copy values across
+ index = xmltree.parse( os.path.join( originDir, "index.xml" ) ).getroot()
+ if "visible" in index.attrib:
+ root.set( "visible", index.attrib.get( "visible" ) )
+ icon = index.find( "icon" )
+ if icon is not None:
+ xmltree.SubElement( root, "icon" ).text = icon.text
+ except:
+ print_exc()
+ # Write the xml file
+ self.indent( root )
+ tree.write( os.path.join( foldername, "index.xml" ), encoding="UTF-8" )
+ else:
+ return
+ elif self.PARAMS[ "type" ] == "rule":
+ # Display list of all elements of a rule
+ RULE.displayRule( self.PARAMS[ "actionPath" ], self.PATH, self.PARAMS[ "rule" ] )
+ return
+ elif self.PARAMS[ "type" ] == "editMatch":
+ # Editing the field the rule is matched against
+ RULE.editMatch( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "content"], self.PARAMS[ "default" ] )
+ elif self.PARAMS[ "type" ] == "editOperator":
+ # Editing the operator of a rule
+ RULE.editOperator( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "group" ], self.PARAMS[ "default" ] )
+ elif self.PARAMS[ "type" ] == "editValue":
+ # Editing the value of a rule
+ RULE.editValue( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ] )
+ elif self.PARAMS[ "type" ] == "browseValue":
+ # Browse for the new value of a rule
+ RULE.browse( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ], self.PARAMS[ "match" ], self.PARAMS[ "content" ] )
+ elif self.PARAMS[ "type" ] == "deleteRule":
+ # Delete a rule
+ RULE.deleteRule( self.PARAMS[ "actionPath" ], self.PARAMS[ "rule" ] )
+ elif self.PARAMS[ "type" ] == "editRulesMatch":
+ # Editing whether any or all rules must match
+ ATTRIB.editMatch( self.PARAMS[ "actionPath" ] )
+ # --- Edit order-by ---
+ elif self.PARAMS[ "type" ] == "orderby":
+ # Display all elements of order by
+ ORDERBY.displayOrderBy( self.PARAMS[ "actionPath" ] )
+ return
+ elif self.PARAMS[ "type" ] == "editOrderBy":
+ ORDERBY.editOrderBy( self.PARAMS[ "actionPath" ], self.PARAMS[ "content" ], self.PARAMS[ "default" ] )
+ elif self.PARAMS[ "type" ] == "editOrderByDirection":
+ ORDERBY.editDirection( self.PARAMS[ "actionPath" ], self.PARAMS[ "default" ] )
+ # --- Edit paths ---
+ elif self.PARAMS[ "type" ] == "addPath":
+ ATTRIB.addPath( self.PARAMS[ "actionPath" ] )
+ elif self.PARAMS[ "type" ] == "editPath":
+ ATTRIB.editPath( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
+ elif self.PARAMS[ "type" ] == "pathRule":
+ PATHRULE.displayRule( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
+ return
+ elif self.PARAMS[ "type" ] == "deletePathRule":
+ ATTRIB.deletePathRule( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
+ elif self.PARAMS[ "type" ] == "editPathMatch":
+ # Editing the field the rule is matched against
+ PATHRULE.editMatch( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
+ elif self.PARAMS[ "type" ] == "editPathValue":
+ # Editing the value of a rule
+ PATHRULE.editValue( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
+ elif self.PARAMS[ "type" ] == "browsePathValue":
+ # Browse for the new value of a rule
+ PATHRULE.browse( self.PARAMS[ "actionPath" ], int( self.PARAMS[ "rule" ] ) )
+ # --- Edit other attribute of view ---
+ # > Content
+ elif self.PARAMS[ "type" ] == "editContent":
+ ATTRIB.editContent( self.PARAMS[ "actionPath" ], "" ) # No default to pass, yet!
+ # > Grouping
+ elif self.PARAMS[ "type" ] == "editGroup":
+ ATTRIB.editGroup( self.PARAMS[ "actionPath" ], self.PARAMS[ "content" ], "" )
+ # > Limit
+ elif self.PARAMS[ "type" ] == "editLimit":
+ ATTRIB.editLimit( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
+ # > Icon (also for node)
+ elif self.PARAMS[ "type" ] == "editIcon":
+ ATTRIB.editIcon( self.PARAMS[ "actionPath" ], self.PARAMS[ "value" ] )
+ elif self.PARAMS[ "type" ] == "browseIcon":
+ ATTRIB.browseIcon( self.PARAMS[ "actionPath" ] )
+ # Refresh the listings and exit
+ xbmc.executebuiltin("Container.Refresh")
+ return
+ if self.PATH.endswith( ".xml" ):
+ self.RulesList()
+ else:
+ self.NodesList(targetDir)
+
+ def NodesList( self, targetDir ):
+ # List nodes and views
+ nodes = {}
+ self.indexCounter = -1
+ if self.PATH != "":
+ self.listNodes( self.PATH, nodes )
+ else:
+ self.listNodes( targetDir, nodes )
+ self.PATH = urllib.quote( self.PATH )
+ for key in nodes:
+ # 0 = Label
+ # 1 = Icon
+ # 2 = Path
+ # 3 = Type
+ # 4 = Order
+ # Localize the label
+ if nodes[ key ][ 0 ].isdigit():
+ label = xbmc.getLocalizedString( int( nodes[ key ][ 0 ] ) )
+ else:
+ label = nodes[ key ][ 0 ]
+ # Create the listitem
+ if nodes[ key ][ 3 ] == "folder":
+ listitem = xbmcgui.ListItem( label="(%s) %s >" % ( nodes[ key ][ 4 ], label ), label2=nodes[ key ][ 4 ], iconImage=nodes[ key ][ 1 ] )
+ else:
+ listitem = xbmcgui.ListItem( label="(%s) %s" % ( nodes[ key ][ 4 ], label ), label2=nodes[ key ][ 4 ], iconImage=nodes[ key ][ 1 ] )
+ # Add context menu items
+ commands = []
+ commandsNode = []
+ commandsView = []
+ commandsNode.append( ( LANGUAGE(30101), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editlabel&actionPath=" % ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + "&label=" + nodes[ key ][ 0 ] + ")" ) )
+ commandsNode.append( ( LANGUAGE(30102), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editIcon&actionPath=" % ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + "&value=" + nodes[ key ][ 1 ] + ")" ) )
+ commandsNode.append( ( LANGUAGE(30103), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseIcon&actionPath=" % ltype + os.path.join( nodes [ key ][ 2 ], "index.xml" ) + ")" ) )
+ commandsNode.append( ( LANGUAGE(30104), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editorder&actionPath=" % ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + ")" ) )
+ commandsNode.append( ( LANGUAGE(30105), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editvisibility&actionPath=" % ltype + os.path.join( nodes[ key ][ 2 ], "index.xml" ) + ")" ) )
+ commandsNode.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % ltype + nodes[ key ][ 2 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30101), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editlabel&actionPath=" % ltype + nodes[ key ][ 2 ] + "&label=" + nodes[ key ][ 0 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30102), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editIcon&actionPath=" % ltype + nodes[ key ][ 2 ] + "&value=" + nodes[ key ][ 1 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30103), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseIcon&actionPath=" % ltype + nodes[ key ][ 2 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30104), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editorder&actionPath=" % ltype + nodes[ key ][ 2 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30105), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=editvisibility&actionPath=" % ltype + nodes[ key ][ 2 ] + ")" ) )
+ commandsView.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % ltype + nodes[ key ][ 2 ] + ")" ) )
+ if nodes[ key ][ 3 ] == "folder":
+ listitem.addContextMenuItems( commandsNode, replaceItems = True )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&path=" % ltype + nodes[ key ][ 2 ], listitem, isFolder=True )
+ else:
+ listitem.addContextMenuItems( commandsView, replaceItems = True )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&path=" % ltype + nodes[ key ][ 2 ], listitem, isFolder=True )
+ if self.PATH != "":
+ # Get any rules from the index.xml
+ rules, nextRule = self.getRules( os.path.join( urllib.unquote( self.PATH ), "index.xml" ), True )
+ rulecount = 0
+ if rules is not None:
+ for rule in rules:
+ commands = []
+ if rule[ 0 ] == "rule":
+ # 1 = field
+ # 2 = operator
+ # 3 = value (optional)
+ if len(rule) == 3:
+ translated = RULE.translateRule( [ rule[ 1 ], rule[ 2 ] ] )
+ else:
+ translated = RULE.translateRule( [ rule[ 1 ], rule[ 2 ], rule[ 3 ] ] )
+ if len(translated) == 2:
+ listitem = xbmcgui.ListItem( label="%s: %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ] ) )
+ else:
+ listitem = xbmcgui.ListItem( label="%s: %s %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ], translated[ 2 ][ 1 ] ) )
+ commands.append( ( LANGUAGE( 30100 ), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deleteRule&actionPath=" % ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( rulecount ) + ")" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( rulecount )
+ rulecount += 1
+ listitem.addContextMenuItems( commands, replaceItems = True )
+ if rule[ 0 ] == "rule" or rule[ 0 ] == "order":
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
+ else:
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ # New rule
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % ltype + os.path.join( self.PATH, "index.xml" ) + "&rule=" + str( nextRule), xbmcgui.ListItem( label=LANGUAGE(30005) ), isFolder=True )
+ showReset = False
+ if self.PATH == "":
+ self.PATH = urllib.quote( targetDir )
+ showReset = True
+ # New view and node
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=newView&actionPath=" % ltype + self.PATH, xbmcgui.ListItem( label=LANGUAGE(30006) ), isFolder=False )
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=newNode&actionPath=" % ltype + self.PATH, xbmcgui.ListItem( label=LANGUAGE(30007) ), isFolder=False )
+ if showReset:
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), "plugin://plugin.library.node.editor?ltype=%s&type=delete&actionPath=" % ltype + targetDir, xbmcgui.ListItem( label=LANGUAGE(30008) ), isFolder=False )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+
+ def RulesList( self ):
+ # List rules for specific view
+ rules, nextRule = self.getRules( self.PATH )
+ hasContent = False
+ content = ""
+ hasOrder = False
+ hasGroup = False
+ hasLimit = False
+ hasPath = False
+ splitPath = None
+ rulecount = 0
+ self.PATH = self.PATH
+ if rules is not None:
+ for rule in rules:
+ commands = []
+ if rule[ 0 ] == "content":
+ # 1 = Content
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30200), ATTRIB.translateContent( rule[ 1 ] ) ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % ltype + self.PATH + "&node=content)" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editContent&actionPath=" % ltype + self.PATH
+ hasContent = True
+ content = rule[ 1 ]
+ elif rule[ 0 ] == "order":
+ # 1 = orderby
+ # 2 = direction (optional?)
+ if len( rule ) == 3:
+ translate = ORDERBY.translateOrderBy( [ rule[ 1 ], rule[ 2 ] ] )
+ listitem = xbmcgui.ListItem( label="%s: %s (%s)" % ( LANGUAGE(30201), translate[ 0 ][ 0 ], translate[ 1 ][ 0 ] ) )
+ else:
+ translate = ORDERBY.translateOrderBy( [ rule[ 1 ], "" ] )
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30201), translate[ 0 ][ 0 ] ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % ltype + self.PATH + "&node=order)" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=orderby&actionPath=" % ltype + self.PATH
+ hasOrder = True
+ elif rule[ 0 ] == "group":
+ # 1 = group
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30202), ATTRIB.translateGroup( rule[ 1 ] ) ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % ltype + self.PATH + "&node=group)" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editGroup&actionPath=" % ltype + self.PATH + "&value=" + rule[ 1 ] + "&content=" + content
+ hasGroup = True
+ elif rule[ 0 ] == "limit":
+ # 1 = limit
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30203), rule[ 1 ] ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % ltype + self.PATH + "&node=limit)" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editLimit&actionPath=" % ltype + self.PATH + "&value=" + rule[ 1 ]
+ hasLimit = True
+ elif rule[ 0 ] == "path":
+ # 1 = path
+ # Split the path into components
+ splitPath = ATTRIB.splitPath( rule[ 1 ] )
+
+ # Add each element of the path to the list
+ for x, component in enumerate( splitPath ):
+ if x == 0:
+ # library://path/
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30204), ATTRIB.translatePath( component ) ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletenode&actionPath=" % ltype + self.PATH + "&node=path)" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=addPath&actionPath=" % ltype + self.PATH
+
+ # Get the rules
+ rules = PATHRULE.getRulesForPath( splitPath[ 0 ] )
+ if x != 0:
+ # Specific component
+
+ # Add the listitem generated from the last component we processed
+ listitem.addContextMenuItems( commands, replaceItems = True )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
+ commands = []
+
+ # Get the rule for this component
+ componentRule = PATHRULE.getMatchingRule( component, rules )
+ translatedComponent = PATHRULE.translateComponent( componentRule, splitPath[ x ] )
+ translatedValue = PATHRULE.translateValue( componentRule, splitPath, x )
+
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( translatedComponent, translatedValue ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deletePathRule&actionPath=%s&rule=%d)" %( ltype, self.PATH, x ) ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=pathRule&actionPath=%s&rule=%d" % ( ltype, self.PATH, x )
+ hasPath = True
+ elif rule[ 0 ] == "rule":
+ # 1 = field
+ # 2 = operator
+ # 3 = value (optional)
+ # 4 = ruleNum
+ if len(rule) == 3:
+ translated = RULE.translateRule( [ rule[ 1 ], rule[ 2 ] ] )
+ else:
+ translated = RULE.translateRule( [ rule[ 1 ], rule[ 2 ], rule[ 3 ] ] )
+ if translated[ 2 ][ 0 ] == "|NONE|":
+ listitem = xbmcgui.ListItem( label="%s: %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ] ) )
+ else:
+ listitem = xbmcgui.ListItem( label="%s: %s %s %s" % ( LANGUAGE(30205), translated[ 0 ][ 0 ], translated[ 1 ][ 0 ], translated[ 2 ][ 1 ] ) )
+ commands.append( ( LANGUAGE(30100), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=deleteRule&actionPath=" % ltype + self.PATH + "&rule=" + str( rule[ 4 ] ) + ")" ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % ltype + self.PATH + "&rule=" + str( rule[ 4 ] )
+ rulecount += 1
+ elif rule[ 0 ] == "match":
+ # 1 = value
+ listitem = xbmcgui.ListItem( label="%s: %s" % ( LANGUAGE(30206), ATTRIB.translateMatch( rule[ 1 ] ) ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editRulesMatch&actionPath=%s" %( ltype, self.PATH )
+ hasGroup = True
+ listitem.addContextMenuItems( commands, replaceItems = True )
+ if rule[ 0 ] == "rule" or rule[ 0 ] == "order" or rule[ 0 ] == "path":
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=True )
+ else:
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ if not hasContent and not hasPath:
+ # Add content
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editContent&actionPath=" % ltype + self.PATH, xbmcgui.ListItem( label=LANGUAGE(30000) ) )
+ if not hasOrder and hasContent:
+ # Add order
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=orderby&actionPath=" % ltype + self.PATH, xbmcgui.ListItem( label=LANGUAGE(30002) ), isFolder=True )
+ if not hasGroup and hasContent:
+ # Add group
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editGroup&actionPath=" % ltype + self.PATH + "&content=" + content, xbmcgui.ListItem( label=LANGUAGE(30004) ) )
+ if not hasLimit and hasContent:
+ # Add limit
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editLimit&actionPath=" % ltype + self.PATH + "&value=25", xbmcgui.ListItem( label=LANGUAGE(30003) ) )
+ if not hasPath and not hasContent:
+ # Add path
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=addPath&actionPath=" % ltype + self.PATH, xbmcgui.ListItem( label=LANGUAGE(30001) ) )
+ if hasContent:
+ # Add rule
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=rule&actionPath=" % ltype + self.PATH + "&rule=" + str( nextRule ), xbmcgui.ListItem( label=LANGUAGE(30005) ), isFolder = True )
+ if hasPath:
+ if "plugin://" not in splitPath[0][0]:
+ # Add component
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=pathRule&actionPath=%s&rule=%d" % ( ltype, self.PATH, x + 1 ), xbmcgui.ListItem( label=LANGUAGE(30009) ), isFolder = True )
+ # Manually edit path
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=%s&type=editPath&actionPath=" % ltype + self.PATH + "&value=" + rule[ 1 ], xbmcgui.ListItem( label=LANGUAGE(30010) ), isFolder = True )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+
+ def _parse_argv( self ):
+ try:
+ p = parse_qs(sys.argv[2][1:])
+ for i in p.keys():
+ p[i] = p[i][0].decode( "utf-8" )
+ self.PARAMS = p
+ except:
+ p = parse_qs(sys.argv[1])
+ for i in p.keys():
+ p[i] = p[i][0].decode( "utf-8" )
+ self.PARAMS = p
+ if "path" in self.PARAMS:
+ self.PATH = self.PARAMS[ "path" ]
+ else:
+ self.PATH = ""
+
+ def getRules( self, actionPath, justRules = False ):
+ returnVal = []
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ if justRules == False:
+ # Look for a 'content'
+ content = root.find( "content" )
+ if content is not None:
+ returnVal.append( ( "content", content.text.decode( "utf-8" ) ) )
+ # Look for an 'order'
+ order = root.find( "order" )
+ if order is not None:
+ if "direction" in order.attrib:
+ returnVal.append( ( "order", order.text, order.attrib.get( "direction" ) ) )
+ else:
+ returnVal.append( ( "order", order.text ) )
+ # Look for a 'group'
+ group = root.find( "group" )
+ if group is not None:
+ returnVal.append( ( "group", group.text ) )
+ # Look for a 'limit'
+ limit = root.find( "limit" )
+ if limit is not None:
+ returnVal.append( ( "limit", limit.text ) )
+ # Look for a 'path'
+ path = root.find( "path" )
+ if path is not None:
+ returnVal.append( ( "path", path.text ) )
+ # Save the current length of the returnVal - we'll insert Match here if there are two or more rules
+ currentLen = len( returnVal )
+ # Look for any rules
+ ruleNum = 0
+ if actionPath.endswith( "index.xml" ):
+ # Load the rules from RULE module
+ rules = RULE.getNodeRules( actionPath )
+ if rules is not None:
+ for rule in rules:
+ returnVal.append( ( "rule", rule[ 0 ], rule[ 1 ], rule[ 2 ], ruleNum ) )
+ ruleNum += 1
+ return returnVal, len( rules )
+ else:
+ return returnVal, 0
+ else:
+ rules = root.findall( "rule" )
+ # Process the rules
+ if rules is not None:
+ for rule in rules:
+ value = rule.find( "value" )
+ if value is not None and value.text is not None:
+ translated = RULE.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text ] )
+ if not RULE.isNodeRule( translated, actionPath ):
+ returnVal.append( ( "rule", rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text, ruleNum ) )
+ else:
+ translated = RULE.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "" ] )
+ if not RULE.isNodeRule( translated, actionPath ):
+ returnVal.append( ( "rule", rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "", ruleNum ) )
+ ruleNum += 1
+ # Get any current match value if there are more than two rules
+ # (if there's only one, the match value doesn't matter)
+ if ruleNum >= 2:
+ matchRules = "all"
+ match = root.find( "match" )
+ if match is not None:
+ matchRules = match.text
+ returnVal.insert( currentLen, ( "match", matchRules ) )
+ return returnVal, len( rules )
+ return returnVal, 0
+ except:
+ print_exc()
+
+ def listNodes( self, targetDir, nodes ):
+ dirs, files = xbmcvfs.listdir( targetDir )
+ for dir in dirs:
+ self.parseNode( os.path.join( targetDir, dir ), nodes )
+ for file in files:
+ self.parseItem( os.path.join( targetDir, file.decode( "utf-8" ) ), nodes )
+
+ def parseNode( self, node, nodes ):
+ # If the folder we've been passed contains an index.xml, send that file to be processed
+ if os.path.exists( os.path.join( node, "index.xml" ) ):
+ # BETA2 ONLY CODE
+ RULE.moveNodeRuleToAppdata( node, os.path.join( node, "index.xml" ) )
+ # /BETA2 ONLY CODE
+ self.parseItem( os.path.join( node, "index.xml" ), nodes, True, node )
+
+ def parseItem( self, file, nodes, isFolder = False, origFolder = None ):
+ if not isFolder and file.endswith( "index.xml" ):
+ return
+ try:
+ # Load the xml file
+ tree = xmltree.parse( file )
+ root = tree.getroot()
+ # Get the item index
+ if "order" in tree.getroot().attrib:
+ index = tree.getroot().attrib.get( "order" )
+ origIndex = index
+ while int( index ) in nodes:
+ index = int( index )
+ index += 1
+ index = str( index )
+ else:
+ self.indexCounter -= 1
+ index = str( self.indexCounter )
+ origIndex = "-"
+ # Get label and icon
+ label = root.find( "label" ).text
+ icon = root.find( "icon" )
+ if icon is not None:
+ icon = icon.text
+ else:
+ icon = ""
+ # Add it to our list of nodes
+ if isFolder:
+ nodes[ int( index ) ] = [ label, icon, urllib.quote( origFolder.decode( "utf-8" ) ), "folder", origIndex ]
+ else:
+ nodes[ int( index ) ] = [ label, icon, file, "item", origIndex ]
+ except:
+ print_exc()
+
+ def getViewElement( self, file, element, newvalue ):
+ try:
+ # Load the file
+ tree = xmltree.parse( file )
+ root = tree.getroot()
+ # Change the element
+ node = root.find( element )
+ if node is not None:
+ return node.text
+ else:
+ return ""
+ except:
+ print_exc()
+
+ def changeViewElement( self, file, element, newvalue ):
+ try:
+ # Load the file
+ tree = xmltree.parse( file )
+ root = tree.getroot()
+ # If the element is content, we can only delete this if there are no
+ # rules, limits, orders
+ if element == "content":
+ rule = root.find( "rule" )
+ order = root.find( "order" )
+ limit = root.find( "limit" )
+ if rule is not None or order is not None or limit is not None:
+ xbmcgui.Dialog().ok( ADDONNAME, LANGUAGE( 30404 ) )
+ return
+ # Find the element
+ node = root.find( element )
+ if node is not None:
+ # If we've been passed an empty value, delete the node
+ if newvalue == "":
+ root.remove( node )
+ else:
+ node.text = newvalue
+ else:
+ # Add a new node
+ if newvalue != "":
+ xmltree.SubElement( root, element ).text = newvalue
+ # Pretty print and save
+ self.indent( root )
+ tree.write( file, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def getRootAttrib( self, file, attrib ):
+ try:
+ # Load the file
+ tree = xmltree.parse( file )
+ root = tree.getroot()
+ # Find the element
+ if attrib in root.attrib:
+ return root.attrib.get( attrib )
+ else:
+ return ""
+ except:
+ print_exc()
+
+ def changeRootAttrib( self, file, attrib, newvalue ):
+ try:
+ # Load the file
+ tree = xmltree.parse( file )
+ root = tree.getroot()
+ # If empty newvalue, delete the attribute
+ if newvalue == "":
+ if attrib in root.attrib:
+ root.attrib.pop( attrib )
+ else:
+ # Change or add the attribute
+ root.set( attrib, newvalue )
+ # Pretty print and save
+ self.indent( root )
+ tree.write( file, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def copyNode(self, dirs, files, target, origin):
+ for file in files:
+ success = xbmcvfs.copy( os.path.join( origin, file ), os.path.join( target, file ) )
+ for dir in dirs:
+ nextDirs, nextFiles = xbmcvfs.listdir( os.path.join( origin, dir ) )
+ self.copyNode( nextDirs, nextFiles, os.path.join( target, dir ), os.path.join( origin, dir ) )
+
+ # in-place prettyprint formatter
+ def indent( self, elem, level=0 ):
+ i = "\n" + level*"\t"
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + "\t"
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ self.indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+
+ # Slugify functions
+ def smart_truncate(string, max_length=0, word_boundaries=False, separator=' '):
+ string = string.strip(separator)
+ if not max_length:
+ return string
+ if len(string) < max_length:
+ return string
+ if not word_boundaries:
+ return string[:max_length].strip(separator)
+ if separator not in string:
+ return string[:max_length]
+ truncated = ''
+ for word in string.split(separator):
+ if word:
+ next_len = len(truncated) + len(word) + len(separator)
+ if next_len <= max_length:
+ truncated += '{0}{1}'.format(word, separator)
+ if not truncated:
+ truncated = string[:max_length]
+ return truncated.strip(separator)
+
+ def slugify(self, text, entities=True, decimal=True, hexadecimal=True, max_length=0, word_boundary=False, separator='-', convertInteger=False):
+ # Handle integers
+ if convertInteger and text.isdigit():
+ text = "NUM-" + text
+ # text to unicode
+ if type(text) != types.UnicodeType:
+ text = unicode(text, 'utf-8', 'ignore')
+ # decode unicode ( ??? = Ying Shi Ma)
+ text = unidecode(text)
+ # text back to unicode
+ if type(text) != types.UnicodeType:
+ text = unicode(text, 'utf-8', 'ignore')
+ # character entity reference
+ if entities:
+ text = CHAR_ENTITY_REXP.sub(lambda m: unichr(name2codepoint[m.group(1)]), text)
+ # decimal character reference
+ if decimal:
+ try:
+ text = DECIMAL_REXP.sub(lambda m: unichr(int(m.group(1))), text)
+ except:
+ pass
+ # hexadecimal character reference
+ if hexadecimal:
+ try:
+ text = HEX_REXP.sub(lambda m: unichr(int(m.group(1), 16)), text)
+ except:
+ pass
+ # translate
+ text = unicodedata.normalize('NFKD', text)
+ if sys.version_info < (3,):
+ text = text.encode('ascii', 'ignore')
+ # replace unwanted characters
+ text = REPLACE1_REXP.sub('', text.lower()) # replace ' with nothing instead with -
+ text = REPLACE2_REXP.sub('-', text.lower())
+ # remove redundant -
+ text = REMOVE_REXP.sub('-', text).strip('-')
+ # smart truncate if requested
+ if max_length > 0:
+ text = smart_truncate(text, max_length, word_boundary, '-')
+ if separator != '-':
+ text = text.replace('-', separator)
+ return text
+
+if ( __name__ == "__main__" ):
+ log('script version %s started' % ADDONVERSION)
+ # Profiling
+ #filename = os.path.join( DATAPATH, strftime( "%Y%m%d%H%M%S",gmtime() ) + "-" + str( random.randrange(0,100000) ) + ".log" )
+ #cProfile.run( 'Main()', filename )
+ #stream = open( filename + ".txt", 'w')
+ #p = pstats.Stats( filename, stream = stream )
+ #p.sort_stats( "cumulative" )
+ #p.print_stats()
+ # No profiling
+ ltype = ''
+ if sys.argv[2] == '':
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=video", xbmcgui.ListItem( label=LANGUAGE(30091) ), isFolder=True )
+ xbmcplugin.addDirectoryItem( int( sys.argv[ 1 ] ), "plugin://plugin.library.node.editor?ltype=music", xbmcgui.ListItem( label=LANGUAGE(30092) ), isFolder=True )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ else:
+ params = dict( arg.split( "=" ) for arg in sys.argv[ 2 ][1:].split( "&" ) )
+ ltype = params['ltype']
+ if ltype != '':
+ import rules, pathrules, viewattrib, orderby
+ RULE = rules.RuleFunctions()
+ ATTRIB = viewattrib.ViewAttribFunctions()
+ PATHRULE = pathrules.PathRuleFunctions()
+ PATHRULE.ATTRIB = ATTRIB
+ ORDERBY = orderby.OrderByFunctions()
+ Main()
+
+ log('script stopped')
diff --git a/plugin.library.node.editor/addon.xml b/plugin.library.node.editor/addon.xml
new file mode 100644
index 0000000..1d2bade
--- /dev/null
+++ b/plugin.library.node.editor/addon.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<addon id="plugin.library.node.editor" name="Library Node Editor" version="1.0.1" provider-name="Unfledged, Team-Kodi">
+ <requires>
+ <import addon="xbmc.python" version="2.25.0"/>
+ <import addon="script.module.unidecode" version="0.4.16"/>
+ </requires>
+ <extension point="xbmc.python.pluginsource" library="addon.py">
+ <provides>executable</provides>
+ </extension>
+ <extension point="xbmc.addon.metadata">
+ <summary lang="de">Benutzerdefinierte Bibliotheksknoten verwalten.</summary>
+ <summary lang="en">Manage custom library nodes.</summary>
+ <summary lang="en_NZ">Manage custom library nodes.</summary>
+ <summary lang="en_US">Manage custom library nodes.</summary>
+ <summary lang="fr">Gére des nœuds de médiathèque personnalisés.</summary>
+ <summary lang="fr_CA">Gérer des nœuds de médiathèque personnalisés.</summary>
+ <summary lang="it">Gestisci nodi libreria personalizzati</summary>
+ <summary lang="ko">사용자 라이브러리 노드 관리자</summary>
+ <summary lang="lt">Tvarkykite savus bibliotekos mazgus.</summary>
+ <summary lang="nl">Beheer aangepaste bibliotheek nodes. </summary>
+ <summary lang="pl">Zarządzanie niestandardowymi węzłami biblioteki.</summary>
+ <summary lang="pt_BR">Gerenciar nós customizados da biblioteca</summary>
+ <summary lang="ro">Administrați noduri mediatecă personalizate</summary>
+ <description lang="de">Benutzerdefinierte Bibliotheksknoten erstellen und bearbeiten.</description>
+ <description lang="en">Create and edit custom library nodes.</description>
+ <description lang="en_NZ">Create and edit custom library nodes.</description>
+ <description lang="en_US">Create and edit custom library nodes.</description>
+ <description lang="fr">Crée et modifie des nœuds de médiathèque personnalisés.</description>
+ <description lang="fr_CA">Créer et modifier des nœuds de médiathèque personnalisés.</description>
+ <description lang="it">Crea e modifica nodi libreria personalizzati.</description>
+ <description lang="ko">사용자 라이브러리 노드를 생성하고 편집합니다.</description>
+ <description lang="lt">Sukurkite ir keiskite savus bibliotekos mazgus.</description>
+ <description lang="nl">Creëer en wijzig aangepaste bibliotheek nodes.</description>
+ <description lang="pl">Tworzenie i edytowanie niestandardowych węzłów biblioteki.</description>
+ <description lang="pt_BR">Crie e edite nós customizados na biblioteca</description>
+ <language></language>
+ <platform>all</platform>
+ <license>GNU General Public License, v2</license>
+ <forum>http://forum.kodi.tv/showthread.php?tid=224512</forum>
+ <email></email>
+ <source>https://github.com/XBMC-Addons/plugin.library.node.editor</source>
+ </extension>
+</addon>
diff --git a/plugin.library.node.editor/changelog.txt b/plugin.library.node.editor/changelog.txt
new file mode 100644
index 0000000..6e3f760
--- /dev/null
+++ b/plugin.library.node.editor/changelog.txt
@@ -0,0 +1,18 @@
+1.0.1
+- updates
+
+1.0.0
+- remove simplejson support
+
+0.0.4
+- cosmetics
+- language update
+
+0.0.3
+- fix studio node creation
+
+0.0.2
+- updated language files from Transifex
+
+0.0.1
+- initial release
diff --git a/plugin.library.node.editor/icon.png b/plugin.library.node.editor/icon.png
new file mode 100755
index 0000000..4a62edf
--- /dev/null
+++ b/plugin.library.node.editor/icon.png
Binary files differ
diff --git a/plugin.library.node.editor/resources/language/Afrikaans/strings.po b/plugin.library.node.editor/resources/language/Afrikaans/strings.po
new file mode 100644
index 0000000..4357a40
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Afrikaans/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Afrikaans (http://www.transifex.com/projects/p/xbmc-addons/language/af/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: af\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Wis uit"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Redigeer etiket"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Soek vir ikoon"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Stop"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Groep"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Stop"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Orden"
diff --git a/plugin.library.node.editor/resources/language/Albanian/strings.po b/plugin.library.node.editor/resources/language/Albanian/strings.po
new file mode 100644
index 0000000..2d5027c
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Albanian/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Albanian (http://www.transifex.com/projects/p/xbmc-addons/language/sq/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sq\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Fshij"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Ndryshoni etiketën"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Vendndodhja"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Vendndodhja"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Porosi nga"
diff --git a/plugin.library.node.editor/resources/language/Amharic/strings.po b/plugin.library.node.editor/resources/language/Amharic/strings.po
new file mode 100644
index 0000000..ba11e37
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Amharic/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Amharic (http://www.transifex.com/projects/p/xbmc-addons/language/am/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: am\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "ማጥፊያ"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "ምልክት ማረሚያ"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "ማቆሚያ"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "ቡድን"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "ማቆሚያ"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "ምልክት"
diff --git a/plugin.library.node.editor/resources/language/Arabic/strings.po b/plugin.library.node.editor/resources/language/Arabic/strings.po
new file mode 100644
index 0000000..8d94642
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Arabic/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Arabic (http://www.transifex.com/projects/p/xbmc-addons/language/ar/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ar\n"
+"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "حذف"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "تحرير العلامة"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "مسار"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "مجموعة"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "مسار"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "ترتيب"
diff --git a/plugin.library.node.editor/resources/language/Armenian/strings.po b/plugin.library.node.editor/resources/language/Armenian/strings.po
new file mode 100644
index 0000000..9e79db0
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Armenian/strings.po
@@ -0,0 +1,29 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Armenian (http://www.transifex.com/projects/p/xbmc-addons/language/hy/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: hy\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Ջնջել"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ուղի"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ուղի"
diff --git a/plugin.library.node.editor/resources/language/Asturian/strings.po b/plugin.library.node.editor/resources/language/Asturian/strings.po
new file mode 100644
index 0000000..f2f21d1
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Asturian/strings.po
@@ -0,0 +1,21 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Asturian (http://www.transifex.com/projects/p/xbmc-addons/language/ast/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ast\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Desaniciar"
diff --git a/plugin.library.node.editor/resources/language/Azerbaijani/strings.po b/plugin.library.node.editor/resources/language/Azerbaijani/strings.po
new file mode 100644
index 0000000..01d5b6d
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Azerbaijani/strings.po
@@ -0,0 +1,29 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Azerbaijani (http://www.transifex.com/projects/p/xbmc-addons/language/az/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: az\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Sil"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Məkan"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Məkan"
diff --git a/plugin.library.node.editor/resources/language/Basque/strings.po b/plugin.library.node.editor/resources/language/Basque/strings.po
new file mode 100644
index 0000000..e5085c2
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Basque/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Basque (http://www.transifex.com/projects/p/xbmc-addons/language/eu/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: eu\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Ezabatu"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editatu etiketa"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Bidea"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Taldea"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Bidea"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenatu"
diff --git a/plugin.library.node.editor/resources/language/Belarusian/strings.po b/plugin.library.node.editor/resources/language/Belarusian/strings.po
new file mode 100644
index 0000000..37f6ad3
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Belarusian/strings.po
@@ -0,0 +1,61 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Belarusian (http://www.transifex.com/projects/p/xbmc-addons/language/be/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: be\n"
+"Plural-Forms: nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Video Library"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Music Library"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Delete"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edit label"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Шлях"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Field"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Group"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Шлях"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Упарадкавана па"
diff --git a/plugin.library.node.editor/resources/language/Bosnian/strings.po b/plugin.library.node.editor/resources/language/Bosnian/strings.po
new file mode 100644
index 0000000..2a0f3db
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Bosnian/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Bosnian (http://www.transifex.com/projects/p/xbmc-addons/language/bs/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: bs\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Izbriši"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Uredi natpis"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupa"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Složi po"
diff --git a/plugin.library.node.editor/resources/language/Bulgarian/strings.po b/plugin.library.node.editor/resources/language/Bulgarian/strings.po
new file mode 100644
index 0000000..7997362
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Bulgarian/strings.po
@@ -0,0 +1,173 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Bulgarian (http://www.transifex.com/projects/p/xbmc-addons/language/bg/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: bg\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Добави съдържание..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Добави път..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Добави подредба..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Добави ограничение..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Добави групиране..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Добави правило..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Видео библиотека"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Музикална библиотека"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Изтрий"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Редактирай етикета"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Редактирай иконата"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Преглед за икона"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Редактирай реда"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Редактирай видимостта"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Добави към главното меню"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Преглед за сойност"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Съдържание"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ред"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Групиране"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Ограничение"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Път"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Правило"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Задайте име"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Задайте условие за видимост"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Начало със стандартните"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Поле"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Оператор"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Стойност"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Тип съдържание"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Съдържание"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Група"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Ограничение"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Път"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Икона"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Подреди по"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Ред"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Наистина ли желаете да го изтриете?"
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Наистина ли желаете да изтриете правилото?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Редът изисква параметър \"Съдържание\""
diff --git a/plugin.library.node.editor/resources/language/Burmese/strings.po b/plugin.library.node.editor/resources/language/Burmese/strings.po
new file mode 100644
index 0000000..5c8b469
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Burmese/strings.po
@@ -0,0 +1,37 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Burmese (http://www.transifex.com/projects/p/xbmc-addons/language/my/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: my\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "ဖျက်ရန်"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "လမ်းကြောင်း"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "အုပ်စု"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "လမ်းကြောင်း"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Order by"
diff --git a/plugin.library.node.editor/resources/language/Catalan/strings.po b/plugin.library.node.editor/resources/language/Catalan/strings.po
new file mode 100644
index 0000000..0d02187
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Catalan/strings.po
@@ -0,0 +1,61 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Catalan (http://www.transifex.com/projects/p/xbmc-addons/language/ca/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ca\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Biblioteca de vídeo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteca de música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Elimina"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edita l'etiqueta"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Cerca una icona"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Camí"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valor"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Camí"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordena per"
diff --git a/plugin.library.node.editor/resources/language/Chinese (Simple)/strings.po b/plugin.library.node.editor/resources/language/Chinese (Simple)/strings.po
new file mode 100644
index 0000000..ad342af
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Chinese (Simple)/strings.po
@@ -0,0 +1,81 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Chinese (Simple) (http://www.transifex.com/projects/p/xbmc-addons/language/zh/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "视频资料库"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "音乐资料库"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "删除"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "编辑标签"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "浏览图标"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "内容"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "路径"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "域"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "算子"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "值"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "内容"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "组"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "路径"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "图标"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "排序"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "方向"
diff --git a/plugin.library.node.editor/resources/language/Chinese (Traditional)/strings.po b/plugin.library.node.editor/resources/language/Chinese (Traditional)/strings.po
new file mode 100644
index 0000000..c27bc79
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Chinese (Traditional)/strings.po
@@ -0,0 +1,53 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Chinese (Traditional) (http://www.transifex.com/projects/p/xbmc-addons/language/zh_TW/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: zh_TW\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "影片資料庫"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "音樂資料庫"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "刪除"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "編輯標籤"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "瀏覽圖示"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "路徑"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "群組"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "路徑"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "排序方式"
diff --git a/plugin.library.node.editor/resources/language/Croatian/strings.po b/plugin.library.node.editor/resources/language/Croatian/strings.po
new file mode 100644
index 0000000..4d57782
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Croatian/strings.po
@@ -0,0 +1,69 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Croatian (http://www.transifex.com/projects/p/xbmc-addons/language/hr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: hr\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videoteka"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Fonoteka"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Obriši"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Uredi oznaku"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Potraži ikonu"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Polje"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Vrijednost"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupa"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Razvrstaj po"
diff --git a/plugin.library.node.editor/resources/language/Czech/strings.po b/plugin.library.node.editor/resources/language/Czech/strings.po
new file mode 100644
index 0000000..0d4b9ff
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Czech/strings.po
@@ -0,0 +1,65 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Czech (http://www.transifex.com/projects/p/xbmc-addons/language/cs/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: cs\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Hudební knihovna"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Smazat"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Upravit popisek"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Vyhledej ikonku"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Cesta"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Pole"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operátor"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Hodnota"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Skupina"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Cesta"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Řadit"
diff --git a/plugin.library.node.editor/resources/language/Danish/strings.po b/plugin.library.node.editor/resources/language/Danish/strings.po
new file mode 100644
index 0000000..fbda394
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Danish/strings.po
@@ -0,0 +1,65 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Danish (http://www.transifex.com/projects/p/xbmc-addons/language/da/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: da\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videobibliotek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Musikbibliotek"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Slet"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Rediger navn"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Se efter ikon"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Indhold"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Sti"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Indhold"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Gruppe"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Sti"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sorter efter"
diff --git a/plugin.library.node.editor/resources/language/Dutch/strings.po b/plugin.library.node.editor/resources/language/Dutch/strings.po
new file mode 100644
index 0000000..4d2cc32
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Dutch/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Dutch (http://www.transifex.com/projects/p/xbmc-addons/language/nl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: nl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Toevoegen inhoud..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Toevoegen pad..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Toevoegen volgorde..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "toevoegen limiet..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "toevoegen groepering..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Toevoegen regel..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Nieuwe node..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nieuw hoofd node..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Herstel bibliotheek nodes naar standaardwaarden..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videobibliotheek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Music Library"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Verwijderen"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Label aanpassen"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Wijzig icoon"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Zoek naar icoon"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Wijzig volgorde"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Aanpassen zichtbaarheid"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Toevoegen aan het startmenu"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Zoek naar waarde"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Inhoud"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Volgorde"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Groepering"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limiet"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Locatie"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regel"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Instellen naam"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Instellen zichtbaarheid conditie"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Instellen volgorde index"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Naam van nieuwe hoofd node"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Start met standaardwaarden"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Veld"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Waarde"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Inhoud type"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Inhoud"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Groep"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limiet"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Locatie"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icoon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sorteren op"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Richting"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Naam van nieuwe node"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Niet gelukt standaard bibliotheek nodes te kopiëren "
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Weet u zeker dat u deze node wilt verwijderen?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Wat u zeker dat u alle nodes wilt herstellen?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Wet u zeker dat u eigendom wilt verwijderen?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Inhoudsparameter kan niet worden verwijder omdat deze node nog steeds een volgorde, limiet of regelparameter heeft."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Wet u zeker dat u deze regel wilt verwijderen?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Volgorde vereist een inhoudsparameter"
diff --git a/plugin.library.node.editor/resources/language/English (Australia)/strings.po b/plugin.library.node.editor/resources/language/English (Australia)/strings.po
new file mode 100644
index 0000000..a95e0a5
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/English (Australia)/strings.po
@@ -0,0 +1,65 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: English (Australia) (http://www.transifex.com/projects/p/xbmc-addons/language/en_AU/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_AU\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Video Library"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Music Library"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Delete"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edit label"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Edit icon"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Browse for icon"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Rule"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Group"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Order by"
diff --git a/plugin.library.node.editor/resources/language/English (New Zealand)/strings.po b/plugin.library.node.editor/resources/language/English (New Zealand)/strings.po
new file mode 100644
index 0000000..dde5b19
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/English (New Zealand)/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: English (New Zealand) (http://www.transifex.com/projects/p/xbmc-addons/language/en_NZ/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_NZ\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Add content..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Add path..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Add order..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Add limit..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Add grouping..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Add rule..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "New node..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "New parent node..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Reset library nodes to default..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Video Library"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Music Library"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Delete"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edit label"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Edit icon"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Browse for icon"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Edit order"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Edit visibility"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Add to main menu"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Browse for value"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Content"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Order"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Grouping"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limit"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Rule"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Set name"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Set visibility condition"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Set order index"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Name of new parent node"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Start with defaults"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Field"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Value"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Content type"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Content"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Group"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limit"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Order by"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direction"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Name of new node"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Unable to copy default library nodes"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Are you sure you want to delete this node?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Are you sure you want to reset all nodes?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Are you sure you want to delete this property?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Are you sure you want to delete this rule?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Order requires a Content parameter"
diff --git a/plugin.library.node.editor/resources/language/English (US)/strings.po b/plugin.library.node.editor/resources/language/English (US)/strings.po
new file mode 100644
index 0000000..28ed57e
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/English (US)/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: English (US) (http://www.transifex.com/projects/p/xbmc-addons/language/en_US/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en_US\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Add content..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Add path..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Add order..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Add limit..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Add grouping..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Add rule..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "New node..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "New parent node..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Reset library nodes to default..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Video Library"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Music Library"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Delete"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edit label"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Edit icon"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Browse for icon"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Edit order"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Edit visibility"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Add to main menu"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Browse for value"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Content"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Order"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Grouping"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limit"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Rule"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Set name"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Set visibility condition"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Set order index"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Name of new parent node"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Start with defaults"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Field"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Value"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Content type"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Content"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Group"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limit"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Order by"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direction"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Name of new node"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Unable to copy default library nodes"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Are you sure you want to delete this node?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Are you sure you want to reset all nodes?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Are you sure you want to delete this property?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Are you sure you want to delete this rule?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Order requires a Content parameter"
diff --git a/plugin.library.node.editor/resources/language/English/strings.po b/plugin.library.node.editor/resources/language/English/strings.po
new file mode 100644
index 0000000..c3065de
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/English/strings.po
@@ -0,0 +1,332 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: English (http://www.transifex.com/projects/p/xbmc-addons/language/en/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: en\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+# Menu items
+msgctxt "#30000"
+msgid "Add content..."
+msgstr ""
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr ""
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr ""
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr ""
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr ""
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr ""
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr ""
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr ""
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr ""
+
+msgctxt "#30009"
+msgid "Add component..."
+msgstr ""
+
+msgctxt "#30010"
+msgid "Manually edit..."
+msgstr ""
+
+#empty strings from id 30011 to 30090
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr ""
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr ""
+
+#empty strings from id 30093 to 30099
+
+# Context menu items
+msgctxt "#30100"
+msgid "Delete"
+msgstr ""
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr ""
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr ""
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr ""
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr ""
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr ""
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr ""
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr ""
+
+#empty strings from id 30108 to 30199
+
+# Other menu item labels
+msgctxt "#30200"
+msgid "Content"
+msgstr ""
+
+msgctxt "#30201"
+msgid "Order"
+msgstr ""
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr ""
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr ""
+
+msgctxt "#30204"
+msgid "Path"
+msgstr ""
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr ""
+
+msgctxt "#30206"
+msgid "Match"
+msgstr ""
+
+#empty strings from id 30207 to 30299
+
+# Titles for dialogs
+msgctxt "#30300"
+msgid "Set name"
+msgstr ""
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr ""
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr ""
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr ""
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr ""
+
+msgctxt "#30305"
+msgid "Field"
+msgstr ""
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr ""
+
+msgctxt "#30307"
+msgid "Value"
+msgstr ""
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr ""
+
+msgctxt "#30309"
+msgid "Content"
+msgstr ""
+
+msgctxt "#30310"
+msgid "Group"
+msgstr ""
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr ""
+
+msgctxt "#30312"
+msgid "Path"
+msgstr ""
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr ""
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr ""
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr ""
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr ""
+
+msgctxt "#30317"
+msgid "Retrieving values..."
+msgstr ""
+
+msgctxt "#30318"
+msgid "Property"
+msgstr ""
+
+#empty strings from id 30319 to 30399
+
+# Messages for dialogs
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr ""
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr ""
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr ""
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr ""
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr ""
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr ""
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr ""
+
+msgctxt "#30407"
+msgid "Are you sure you want to delete this component?"
+msgstr ""
+
+msgctxt "#30408"
+msgid "Custom property..."
+msgstr ""
+
+msgctxt "#30409"
+msgid "No options to select from were found"
+msgstr ""
+
+msgctxt "#30410"
+msgid "Getting plugin listings..."
+msgstr ""
+
+msgctxt "#30411"
+msgid "Link path to here"
+msgstr ""
+
+#empty strings from id 30412 to 30499
+
+# Labels for path rules
+
+msgctxt "#30500"
+msgid "Genre ID"
+msgstr ""
+
+msgctxt "#30501"
+msgid "Country ID"
+msgstr ""
+
+msgctxt "#30502"
+msgid "Studio ID"
+msgstr ""
+
+msgctxt "#30503"
+msgid "Director ID"
+msgstr ""
+
+msgctxt "#30504"
+msgid "Actor ID"
+msgstr ""
+
+msgctxt "#30505"
+msgid "Set ID"
+msgstr ""
+
+msgctxt "#30506"
+msgid "Tag ID"
+msgstr ""
+
+msgctxt "#30507"
+msgid "TV Show ID"
+msgstr ""
+
+msgctxt "#30508"
+msgid "Artist ID"
+msgstr ""
+
+msgctxt "#30509"
+msgid "Album ID"
+msgstr ""
+
+msgctxt "#30510"
+msgid "Role ID"
+msgstr ""
+
+msgctxt "#30511"
+msgid "Song ID"
+msgstr ""
+
+msgctxt "#30512"
+msgid "Album artists only"
+msgstr ""
+
+msgctxt "#30513"
+msgid "Show singles"
+msgstr ""
+
+msgctxt "#30514"
+msgid "Plugin..."
+msgstr ""
diff --git a/plugin.library.node.editor/resources/language/Esperanto/strings.po b/plugin.library.node.editor/resources/language/Esperanto/strings.po
new file mode 100644
index 0000000..6bdc7ae
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Esperanto/strings.po
@@ -0,0 +1,25 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Esperanto (http://www.transifex.com/projects/p/xbmc-addons/language/eo/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: eo\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Forigi"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editii Label"
diff --git a/plugin.library.node.editor/resources/language/Estonian/strings.po b/plugin.library.node.editor/resources/language/Estonian/strings.po
new file mode 100644
index 0000000..cedcf65
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Estonian/strings.po
@@ -0,0 +1,49 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Estonian (http://www.transifex.com/projects/p/xbmc-addons/language/et/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: et\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Kustuta"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Muuda silti"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Sirvi ikoone"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Asukoht"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupp"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Asukoht"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikoon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Järjesta"
diff --git a/plugin.library.node.editor/resources/language/Faroese/strings.po b/plugin.library.node.editor/resources/language/Faroese/strings.po
new file mode 100644
index 0000000..903988c
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Faroese/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Faroese (http://www.transifex.com/projects/p/xbmc-addons/language/fo/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fo\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Strika"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Broyt heiti"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Stíggi"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Bólkur"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Stíggi"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Skipa eftir"
diff --git a/plugin.library.node.editor/resources/language/Finnish/strings.po b/plugin.library.node.editor/resources/language/Finnish/strings.po
new file mode 100644
index 0000000..3563a49
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Finnish/strings.po
@@ -0,0 +1,57 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Finnish (http://www.transifex.com/projects/p/xbmc-addons/language/fi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fi\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videokirjasto"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Musiikkikirjasto"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Poista"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Muuta nimeä"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Hae kuvake"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Polku"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Ryhmä"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Polku"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Kuvake"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Järjestys"
diff --git a/plugin.library.node.editor/resources/language/French (Canada)/strings.po b/plugin.library.node.editor/resources/language/French (Canada)/strings.po
new file mode 100644
index 0000000..e91b3e0
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/French (Canada)/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: French (Canada) (http://www.transifex.com/projects/p/xbmc-addons/language/fr_CA/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fr_CA\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Ajouter du contenu..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Ajouter un chemin..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Ajouter un ordre..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Ajouter une limite..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Ajouter un regroupement..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Ajouter une règle..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Nouveau nœud..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nouveau nœud parent..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Réinitialiser les nœuds de médiathèque à leurs valeurs par défaut..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Vidéothèque"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Audiothèque"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Supprimer"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Modifier l'étiquette"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Modifier l'icône"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Rechercher des icônes"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Modifier l'ordre"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Modifier la visibilité"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Ajouter au menu principal"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Rechercher une valeur"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Contenu"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ordre"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Regroupement"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Chemin"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Règle"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Définir un nom"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Définir une condition de visibilité"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Définir l'index d'ordre"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Nom du nouveau nœud parent"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Démarrer avec les valeurs par défaut"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Champ"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Opérateur"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valeur"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Type de contenu"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Contenu"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Groupe"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Chemin"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icône"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ranger par"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direction"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nom du nouveau nœud"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Impossible de copier les nœuds de médiathèque par défaut"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Voulez-vous vraiment supprimer ce nœud?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Voulez-vous vraiment réinitialiser tous les nœuds?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Voulez-vous vraiment supprimer cette propriété?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Le paramètre de contenu ne peut pas être supprimé tant que le nœud à une paramètre d'Ordre, de Limite ou de Règle."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Voulez-vous vraiment supprimer cette règle?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "L'Ordre exige un paramètre de Contenu"
diff --git a/plugin.library.node.editor/resources/language/French/strings.po b/plugin.library.node.editor/resources/language/French/strings.po
new file mode 100644
index 0000000..31fbf58
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/French/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: French (http://www.transifex.com/projects/p/xbmc-addons/language/fr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fr\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Ajouter du contenu…"
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Ajouter un chemin…"
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Ajouter un ordre…"
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Ajouter une limite…"
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Ajouter un regroupement…"
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Ajouter une règle…"
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Nouveau nœud…"
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nouveau nœud parent…"
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Réinitialiser les nœuds de médiathèque aux valeurs par défaut…"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Vidéothèque"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Audiothèque"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Supprimer"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Éditer le nom"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Éditer l'icône"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Rechercher des icônes"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Éditer l'ordre"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Éditer la visibilité"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Ajouter au menu principal"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Chercher une valeur"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Contenu"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ordre"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Regroupement"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Chemin"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Règle"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Définir un nom"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Définir une condition de visibilité"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Définir un index d'ordre"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Nom du nouveau nœud parent"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Commencer avec les réglages par défaut"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Champ"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Opérateur"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valeur"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Type de contenu"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Contenu"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Groupe"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Chemin"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icône"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Trier par"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direction"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nom du nouveau nœud"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Impossible de copier les nœuds de médiathèque par défaut"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Faut-il vraiment supprimer ce nœud ?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Faut-il vraiment réinitialiser tous les nœuds ?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Faut-il vraiment supprimer cette propriété ?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Le paramètre de contenu ne peut pas être supprimé tant que le nœud possède un paramètre d'ordre, de limite ou de règle."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Faut-il vraiment supprimer cette règle ?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "L'ordre requiert un paramètre de Contenu"
diff --git a/plugin.library.node.editor/resources/language/Galician/strings.po b/plugin.library.node.editor/resources/language/Galician/strings.po
new file mode 100644
index 0000000..710a98b
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Galician/strings.po
@@ -0,0 +1,177 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Galician (http://www.transifex.com/projects/p/xbmc-addons/language/gl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: gl\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Engadir contido..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Engadir ruta..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Engadir orde..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Engadir limite..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Engadir regra..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Novo nodo..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Novo nodo pai..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Biblioteca de Vídeo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteca de Música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Eliminar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Editar icona"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Buscar icona"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Editar orde"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Editar visibilidade"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Engadir ó menú principal"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Buscar un valor"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Contido"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Orde"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Límite"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regra"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Estabelecer nome"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Estabelecer condición de visibilidade"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Campo"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operador"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valor"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Tipo de contido"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Contido"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Límite"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordear por"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Dirección"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nome do novo nodo"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Tes a certeza de querer eliminar este nodo?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Tes a certeza de querer restabelecer todos os nodos?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Tes a certeza de querer eliminar esta propiedade?"
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Tes a certeza de querer eliminar esta regra?"
diff --git a/plugin.library.node.editor/resources/language/German/strings.po b/plugin.library.node.editor/resources/language/German/strings.po
new file mode 100644
index 0000000..0bf2c37
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/German/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: German (http://www.transifex.com/projects/p/xbmc-addons/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"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Inhalt hinzufügen..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Pfad hinzufügen..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Sortierung hinzufügen..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Beschränkung hinzufügen..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Gruppierung hinzufügen..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Regel hinzufügen..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Neuer Knoten..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Neuer übergeordneter Knoten..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Bibliotheksknoten auf Standard zurücksetzen..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videobibliothek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Musikbibliothek"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Löschen"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Beschriftung ändern"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Symbol bearbeiten"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Nach Symbol suchen"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Sortierung bearbeiten"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Sichtbarkeit bearbeiten"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Zum Hauptmenü hinzufügen"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Nach Wert suchen"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Inhalt"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Sortierung"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Gruppierung"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Beschränkung"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Pfad"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regel"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Name festlegen"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Sichtbarkeitsbedingung festlegen"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Sortierungsindex festlegen"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Name des neuen übergeordneten Knotens"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Mit Standardeinstellungen starten"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Feld"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Betreiber"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Wert"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Inhaltstyp"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Inhalt"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Gruppe"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Beschränkung"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Pfad"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Symbol"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sortieren nach"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Richtung"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Name des neuen Knotens"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Standardbibliotheksknoten können nicht kopiert werden"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Sind Sie Sicher, dass Sie diesen Knoten löschen möchten?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Sind Sie Sicher, dass Sie alle Knoten zurücksetzen möchten?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Sind Sie Sicher, dass Sie diese Eigenschaft löschen möchten?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Inhaltsparameter kann nicht gelöscht werden, solange dieser Knoten noch eine Sortierung, Beschränkung oder Regel enthält."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Sind Sie Sicher, dass Sie diese Regel löschen möchten?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Sortierung benötigt einen Inhaltsparameter"
diff --git a/plugin.library.node.editor/resources/language/Greek/strings.po b/plugin.library.node.editor/resources/language/Greek/strings.po
new file mode 100644
index 0000000..b8b7577
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Greek/strings.po
@@ -0,0 +1,121 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Greek (http://www.transifex.com/projects/p/xbmc-addons/language/el/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: el\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Συλλογή Βίντεο"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Μουσική Συλλογή"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Διαγραφή"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Επεξεργασία ετικέτας"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Επεξεργασία εικονιδίου"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Αναζήτηση εικονιδίου"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Επεξεργασία Σειράς"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Επεξεργασία Ορατότητας"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Προσθήκη στο κεντρικό μενού"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Περιεχόμενο"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Σειρά"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Ομαδοποίηση"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Όριο"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Διαδρομή"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Κανόνας"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Ορισμός Ονόματος"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Πεδίο"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Χειριστής"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Τιμή"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Περιεχόμενο"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Γκρουπ"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Όριο"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Διαδρομή"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Εικονίδιο"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Σειρά κατά"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Κατεύθυνση"
diff --git a/plugin.library.node.editor/resources/language/Haitian (Haitian Creole)/strings.po b/plugin.library.node.editor/resources/language/Haitian (Haitian Creole)/strings.po
new file mode 100644
index 0000000..f24babd
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Haitian (Haitian Creole)/strings.po
@@ -0,0 +1,21 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Haitian (Haitian Creole) (http://www.transifex.com/projects/p/xbmc-addons/language/ht/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ht\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Efface"
diff --git a/plugin.library.node.editor/resources/language/Hebrew/strings.po b/plugin.library.node.editor/resources/language/Hebrew/strings.po
new file mode 100644
index 0000000..ae80af7
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Hebrew/strings.po
@@ -0,0 +1,157 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Hebrew (http://www.transifex.com/projects/p/xbmc-addons/language/he/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: he\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "הוספת תוכן ..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "הוספת נתיב ..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "הוספת גבול ..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "הוספת הקבצה ..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "הוספת כלל ..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "ספריית וידאו"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "ספריית מוזיקה "
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "מחיקה"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "עריכת תווית"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "עריכת סמל"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "בחירת סמל"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "הוסף לתפריט ראשי"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "חפש ערך"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "תוכן"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "סדר"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "קיבוץ"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "מגבלה"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "נתיב"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "חוק"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "שם נקבע"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "התחל עם ברירת מחדל"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "שדה"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "אופרטור"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "ערך"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "סוג תוכן"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "תוכן"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "קבוצה"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "מגבלה"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "נתיב"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "אייקון"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "סדר לפי"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "כיוון"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "האם אתה בטוח שאתה רוצה למחוק את הנכס הזה?"
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "האם אתה בטוח שאתה רוצה למחוק את הכלל הזה?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "הצו מחייב פרמטר תוכן"
diff --git a/plugin.library.node.editor/resources/language/Hindi (Devanagiri)/strings.po b/plugin.library.node.editor/resources/language/Hindi (Devanagiri)/strings.po
new file mode 100644
index 0000000..f05728b
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Hindi (Devanagiri)/strings.po
@@ -0,0 +1,29 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Hindi (Devanagiri) (http://www.transifex.com/projects/p/xbmc-addons/language/hi/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: hi\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "मिटाना"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "पथ"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "पथ"
diff --git a/plugin.library.node.editor/resources/language/Hungarian/strings.po b/plugin.library.node.editor/resources/language/Hungarian/strings.po
new file mode 100644
index 0000000..a998189
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Hungarian/strings.po
@@ -0,0 +1,81 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Hungarian (http://www.transifex.com/projects/p/xbmc-addons/language/hu/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: hu\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videó könytár"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Zene könyvtár"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Törlés"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Cím szerkesztése"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Ikon keresése"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Tartalom"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Útvonal"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Mező"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Üzemeltető"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Érték"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Tartalom"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Csoport"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Útvonal"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Rendezés"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Irány"
diff --git a/plugin.library.node.editor/resources/language/Icelandic/strings.po b/plugin.library.node.editor/resources/language/Icelandic/strings.po
new file mode 100644
index 0000000..62f903a
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Icelandic/strings.po
@@ -0,0 +1,61 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Icelandic (http://www.transifex.com/projects/p/xbmc-addons/language/is/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: is\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Myndbandasafn"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Tónlistarsafn"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Eyða"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Breyta nafni"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Fletta eftir táknmynd"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Slóð"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Gildi"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Hópur"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Slóð"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Tákn"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Raða eftir"
diff --git a/plugin.library.node.editor/resources/language/Indonesian/strings.po b/plugin.library.node.editor/resources/language/Indonesian/strings.po
new file mode 100644
index 0000000..8083227
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Indonesian/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Indonesian (http://www.transifex.com/projects/p/xbmc-addons/language/id/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: id\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Hapus"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edit Label"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Ramban ikon"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Path"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Order berdasar"
diff --git a/plugin.library.node.editor/resources/language/Italian/strings.po b/plugin.library.node.editor/resources/language/Italian/strings.po
new file mode 100644
index 0000000..8933aec
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Italian/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Italian (http://www.transifex.com/projects/p/xbmc-addons/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"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Aggiungi contenuto..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Aggiungi percorso..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Aggiungi ordine..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Aggiungi limite..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Aggiungi raggruppamento..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Aggiungi regola..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Nuovo nodo..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nuovo nodo superiore..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Ripristina nodi libreria a predefinito..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Libreria Video"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Libreria Musicale"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Elimina"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Modifica etichetta"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Modifica icona"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Cerca icona"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Modifica ordine"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Modifica visibilita'"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Aggiungi a menu' principale"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Cerca valore"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Contenuto"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ordine"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Raggruppamento"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Percorso"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regola"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Imposta nome"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Imposta condizione visibilita'"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Imposta ordine indice"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Nome del nuovo nodo superiore"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Parti con predefiniti"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Campo"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operatore"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valore"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Tipo contenuto"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Contenuto"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Gruppo"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Percorso"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordina per"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direzione"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nome del nuovo nodo"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Impossibile copiare i nodi libreria predefiniti"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Sei sicuro di voler eliminare questo nodo?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Sei sicuro di voler resettare tutti i nodi?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Sei sicuro di voler cancellare questa proprieta'?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Il parametro del contenuto non può essere cancellato finche' questo nodo ha ancora un parametro Ordine, Limite o Regola."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Sei sicuro di voler cancellare questa regola?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "L'Ordine richiede un parametro Contenuto"
diff --git a/plugin.library.node.editor/resources/language/Japanese/strings.po b/plugin.library.node.editor/resources/language/Japanese/strings.po
new file mode 100644
index 0000000..312d35f
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Japanese/strings.po
@@ -0,0 +1,53 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Japanese (http://www.transifex.com/projects/p/xbmc-addons/language/ja/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ja\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "ビデオライブラリ"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "ミュージックライブラリ"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "削除"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "ラベル編集"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "アイコンをブラウズ"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "パス"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "グループ"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "パス"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "並べ替え"
diff --git a/plugin.library.node.editor/resources/language/Korean/strings.po b/plugin.library.node.editor/resources/language/Korean/strings.po
new file mode 100644
index 0000000..2245056
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Korean/strings.po
@@ -0,0 +1,153 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Korean (http://www.transifex.com/projects/p/xbmc-addons/language/ko/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ko\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "콘텐츠 추가..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "경로 추가..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "순서 추가..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "규칙 추가..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "새 노드..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "새 상위 노드..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "라이브러리 노드를 기본값으로 초기화..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "비디오 라이브러리"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "음악 라이브러리"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "삭제"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "레이블 수정"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "아이콘 편집"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "아이콘 찾기"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "순서 편집"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "메인 메뉴에 추가"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "콘텐츠"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "순서"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "경로"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "규칙"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "이름 설정"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "새 상위 노드 이름"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "값"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "콘텐츠 종류"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "콘텐츠"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "그룹"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "경로"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "아이콘"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "정렬순서"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "방향"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "새 노느 이름"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "기본 라이브러리 노드를 복사할 수 없습니다"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "이 노드를 삭제하겠습니까?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "모든 노드를 초기화 하겠습니까?"
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "이 규칙을 삭제하겠습니까?"
diff --git a/plugin.library.node.editor/resources/language/Latvian/strings.po b/plugin.library.node.editor/resources/language/Latvian/strings.po
new file mode 100644
index 0000000..e148b7a
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Latvian/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Latvian (http://www.transifex.com/projects/p/xbmc-addons/language/lv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: lv\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Dzēst"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Labot etiķeti"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Pārlūkot ikonu"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ceļš"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupa"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ceļš"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sakārto pēc"
diff --git a/plugin.library.node.editor/resources/language/Lithuanian/strings.po b/plugin.library.node.editor/resources/language/Lithuanian/strings.po
new file mode 100644
index 0000000..1708c7a
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Lithuanian/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Lithuanian (http://www.transifex.com/projects/p/xbmc-addons/language/lt/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: lt\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Pridėti turinį..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Pridėti kelią..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Pridėti rikiavimą..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Pridėti apribojimą..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "ridėti grupavimą..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Pridėti taisyklę..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Naujas mazgą..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Naujas pagrindinis mazgas..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Atstatyti numatytuosius bibliotekos mazgus..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Vaizdo biblioteka"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Muzikos biblioteka"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Šalinti"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Keisti etiketę"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Keisti piktogramą"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Parinkti piktogramą"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Keisti rikiavimą"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Keisti matomumą"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Pridėti į pagrindinį meniu"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Parinkti reikšmę"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Turinys"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Rikiavimas"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Grupavimas"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Apribojimas"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Kelias"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Taisyklė"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Nustatyti vardą"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Nustatyti matomumo sąlygą"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Nustatyti rikiavimo indeksą"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Naujo pagrindinio mazgo vardas"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Pradėti su numatytomis reikšmėmis"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Laukas"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operatorius"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Reikšmė"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Turinio tipas"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Turinys"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupė"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Apribojimas"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Kelias"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Piktograma"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Rikiuoti pagal"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Kryptis"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Naujo mazgo vardas"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Neįmanoma nukopijuoti numatytųjų bibliotekos mazgų"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Ar tikrai norite pašalinti šį mazgą?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Ar tikrai norite atstatyti visus mazgus?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Ar tikrai norite pašalinti šią savybę?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Turinio parametras negali būti pašalintas, kol mazgas vis dar turi rikiavimo, apribojimo ar taisyklės parametrą."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Ar tikrai norite pašalinti šią taisyklę?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Rikiavimui reikalingas turinio parametras"
diff --git a/plugin.library.node.editor/resources/language/Macedonian/strings.po b/plugin.library.node.editor/resources/language/Macedonian/strings.po
new file mode 100644
index 0000000..bae004d
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Macedonian/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Macedonian (http://www.transifex.com/projects/p/xbmc-addons/language/mk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: mk\n"
+"Plural-Forms: nplurals=2; plural=(n % 10 == 1 && n % 100 != 11) ? 0 : 1;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Избриши"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Уреди натпис"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Барај икона"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Патека"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Група"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Патека"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Подреди по"
diff --git a/plugin.library.node.editor/resources/language/Malay/strings.po b/plugin.library.node.editor/resources/language/Malay/strings.po
new file mode 100644
index 0000000..04d1272
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Malay/strings.po
@@ -0,0 +1,69 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Malay (http://www.transifex.com/projects/p/xbmc-addons/language/ms/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ms\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Pustaka Video"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Pustaka Muzik"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Hapus"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Sunting label"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Sunting ikon"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Kandungan"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Laluan"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Peraturan"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Kandungan"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Kumpulan"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Laluan"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikon"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Arah"
diff --git a/plugin.library.node.editor/resources/language/Malayalam/strings.po b/plugin.library.node.editor/resources/language/Malayalam/strings.po
new file mode 100644
index 0000000..bcaae4c
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Malayalam/strings.po
@@ -0,0 +1,21 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Malayalam (http://www.transifex.com/projects/p/xbmc-addons/language/ml/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ml\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "കളയുക"
diff --git a/plugin.library.node.editor/resources/language/Maltese/strings.po b/plugin.library.node.editor/resources/language/Maltese/strings.po
new file mode 100644
index 0000000..9a00323
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Maltese/strings.po
@@ -0,0 +1,29 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Maltese (http://www.transifex.com/projects/p/xbmc-addons/language/mt/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: mt\n"
+"Plural-Forms: nplurals=4; plural=(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Ħassar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Biddel l-Label"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Issortja"
diff --git a/plugin.library.node.editor/resources/language/Mongolian (Mongolia)/strings.po b/plugin.library.node.editor/resources/language/Mongolian (Mongolia)/strings.po
new file mode 100644
index 0000000..b83ed0a
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Mongolian (Mongolia)/strings.po
@@ -0,0 +1,25 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Mongolian (Mongolia) (http://www.transifex.com/projects/p/xbmc-addons/language/mn_MN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: mn_MN\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Устгах"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Групп"
diff --git a/plugin.library.node.editor/resources/language/Norwegian/strings.po b/plugin.library.node.editor/resources/language/Norwegian/strings.po
new file mode 100644
index 0000000..796b803
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Norwegian/strings.po
@@ -0,0 +1,65 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Norwegian (http://www.transifex.com/projects/p/xbmc-addons/language/no/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: no\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videobibliotek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Musikk Bibliotek"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Slett"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Rediger plateselskap"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Bla etter ikon"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Sti"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Verdi"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Gruppe"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Sti"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sorter etter"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Retning"
diff --git a/plugin.library.node.editor/resources/language/Persian (Iran)/strings.po b/plugin.library.node.editor/resources/language/Persian (Iran)/strings.po
new file mode 100644
index 0000000..d96074d
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Persian (Iran)/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Persian (Iran) (http://www.transifex.com/projects/p/xbmc-addons/language/fa_IR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fa_IR\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "کتابخانه ی ویدیو"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "کتابخانه ی موسیقی"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "حذف"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "ویرایش برچسب"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "مسیر"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "گروه"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "مسیر"
diff --git a/plugin.library.node.editor/resources/language/Persian/strings.po b/plugin.library.node.editor/resources/language/Persian/strings.po
new file mode 100644
index 0000000..e2a4d5b
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Persian/strings.po
@@ -0,0 +1,21 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Persian (http://www.transifex.com/projects/p/xbmc-addons/language/fa/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fa\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "حذف"
diff --git a/plugin.library.node.editor/resources/language/Polish/strings.po b/plugin.library.node.editor/resources/language/Polish/strings.po
new file mode 100644
index 0000000..3239b1e
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Polish/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Polish (http://www.transifex.com/projects/p/xbmc-addons/language/pl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pl\n"
+"Plural-Forms: nplurals=3; plural=(n==1 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Dodaj zawartość..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Dodaj ścieżkę..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Dodaj kolejność..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Dodaj ograniczenie..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Dodaj grupowanie..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Dodaj regułę..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Dodaj węzeł..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nowy węzeł nadrzędny..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Przywróć domyśle węzły biblioteki..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Biblioteka wideo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteka muzyki"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Usuń"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Edytuj etykietę"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Edytuj ikonę"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Wybierz ikonę"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Edytuj kolejność"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Edytuj widoczność"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Dodaj do menu startowego"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Wybierz wartość"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Zawartość"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Kolejność"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Grupowanie"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Ograniczenie"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ścieżka"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Reguła"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Ustaw nazwę"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Ustaw warunek widoczności"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Ustaw indeks kolejności"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Nazwa nowego węzła nadrzędnego"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Rozpocznij z domyślnymi"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Pole"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Wartość"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Typ zawartości"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Zawartość"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupa"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Ograniczenie"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ścieżka"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sortuj wg"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Kierunek"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nazwa nowego węzła"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Nieudane kopiowanie domyślnych węzłów biblioteki"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Jesteś pewien, że chcesz usunąć ten węzeł?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Jesteś pewien, że chcesz wyczyścić wszystkie węzły?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Jesteś pewien, że chcesz usunąć tę właściwość?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Parametr zawartości nie może zostać usunięty, gdy ten węzeł ciągle ma parametr kolejności, ograniczenia lub regułę."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Jesteś pewien, że chcesz usunąć tę regułę?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Kolejność wymaga parametru zawartości"
diff --git a/plugin.library.node.editor/resources/language/Portuguese (Brazil)/strings.po b/plugin.library.node.editor/resources/language/Portuguese (Brazil)/strings.po
new file mode 100644
index 0000000..2af9612
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Portuguese (Brazil)/strings.po
@@ -0,0 +1,213 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Portuguese (Brazil) (http://www.transifex.com/projects/p/xbmc-addons/language/pt_BR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pt_BR\n"
+"Plural-Forms: nplurals=2; plural=(n > 1);\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Adicionar conteúdo..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Adicionar caminho..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Adicionar ordem..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Adicionar limite..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Adicionar agrupando..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Adicionar regra..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Novo nó..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Novo nó principal..."
+
+msgctxt "#30008"
+msgid "Reset library nodes to default..."
+msgstr "Resetar os nós da biblioteca para valores padrões..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Coleção de Vídeo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Coleção de Músicas"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Delete"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Editar ícone"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Procurar por logo do canal"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Editar ordem"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Editar visibilidade"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Adicionar ao menu principal"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Procurar pelo valor"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Conteúdo"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ordem"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Agrupando"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Caminho"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regra"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Defina nome"
+
+msgctxt "#30301"
+msgid "Set visibility condition"
+msgstr "Defina condição de visibilidade"
+
+msgctxt "#30302"
+msgid "Set order index"
+msgstr "Definir ordem de indexação"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Nome do novo nó principal"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Iniciar com valores padrões"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Campo"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operador"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valor"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Tipo do Conteúdo"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Conteúdo"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limite"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Caminho"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ícone"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenar por"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direção"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Nome do novo nó"
+
+msgctxt "#30400"
+msgid "Unable to copy default library nodes"
+msgstr "Não foi possível copiar os nós de biblioteca padrão"
+
+msgctxt "#30401"
+msgid "Are you sure you want to delete this node?"
+msgstr "Tem certeza que deseja deletar este nó?"
+
+msgctxt "#30402"
+msgid "Are you sure you want to reset all nodes?"
+msgstr "Tem certeza que deseja resetar todos os nós?"
+
+msgctxt "#30403"
+msgid "Are you sure you want to delete this property?"
+msgstr "Tem certeza que deseja deletar esta propriedade?"
+
+msgctxt "#30404"
+msgid "Content parameter can't be deleted whilst this node still has an Order, Limit or Rule parameter."
+msgstr "Parâmetro do conteúdo não pode ser excluído enquanto esse nó ainda tiver um parâmetro de ordem, limite ou regra."
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Tem certeza que deseja deletar esta regra?"
+
+msgctxt "#30406"
+msgid "Order requires a Content parameter"
+msgstr "Ordenar requer um parâmetro de Conteúdo"
diff --git a/plugin.library.node.editor/resources/language/Portuguese/strings.po b/plugin.library.node.editor/resources/language/Portuguese/strings.po
new file mode 100644
index 0000000..d7b656e
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Portuguese/strings.po
@@ -0,0 +1,73 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Portuguese (http://www.transifex.com/projects/p/xbmc-addons/language/pt/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: pt\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Biblioteca de Vídeo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteca de Música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Apagar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Procurar ícone"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Caminho"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Campo"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operador"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valor"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Caminho"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ícone"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenar"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direcção"
diff --git a/plugin.library.node.editor/resources/language/Romanian/strings.po b/plugin.library.node.editor/resources/language/Romanian/strings.po
new file mode 100644
index 0000000..658c1d7
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Romanian/strings.po
@@ -0,0 +1,177 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Romanian (http://www.transifex.com/projects/p/xbmc-addons/language/ro/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ro\n"
+"Plural-Forms: nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));\n"
+
+msgctxt "#30000"
+msgid "Add content..."
+msgstr "Adăugare conținut..."
+
+msgctxt "#30001"
+msgid "Add path..."
+msgstr "Adăugare cale..."
+
+msgctxt "#30002"
+msgid "Add order..."
+msgstr "Adăugare ordonare..."
+
+msgctxt "#30003"
+msgid "Add limit..."
+msgstr "Adăugare limită..."
+
+msgctxt "#30004"
+msgid "Add grouping..."
+msgstr "Adăugare grupare..."
+
+msgctxt "#30005"
+msgid "Add rule..."
+msgstr "Adăugare regulă..."
+
+msgctxt "#30006"
+msgid "New node..."
+msgstr "Nod nou..."
+
+msgctxt "#30007"
+msgid "New parent node..."
+msgstr "Nod părinte nou..."
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Mediatecă video"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Mediatecă audio"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Șterge"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Modificare etichetă"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Modificare pictogramă"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Răsfoire după pictogramă"
+
+msgctxt "#30104"
+msgid "Edit order"
+msgstr "Modificare ordonare"
+
+msgctxt "#30105"
+msgid "Edit visibility"
+msgstr "Modificare vizibilitate"
+
+msgctxt "#30106"
+msgid "Add to main menu"
+msgstr "Adaugă la meniul principal"
+
+msgctxt "#30107"
+msgid "Browse for value"
+msgstr "Răsfoire după valoare"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Conținut"
+
+msgctxt "#30201"
+msgid "Order"
+msgstr "Ordonare"
+
+msgctxt "#30202"
+msgid "Grouping"
+msgstr "Grupare"
+
+msgctxt "#30203"
+msgid "Limit"
+msgstr "Limită"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Cale"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regulă"
+
+msgctxt "#30300"
+msgid "Set name"
+msgstr "Definire nume"
+
+msgctxt "#30303"
+msgid "Name of new parent node"
+msgstr "Numele noului nod părinte"
+
+msgctxt "#30304"
+msgid "Start with defaults"
+msgstr "Pornește cu cele implicite"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Câmp"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operator"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valoare"
+
+msgctxt "#30308"
+msgid "Content type"
+msgstr "Tip conținut"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Conținut"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "#30311"
+msgid "Limit"
+msgstr "Limită"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Cale"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Pictogramă"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordonează după"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Direcție"
+
+msgctxt "#30316"
+msgid "Name of new node"
+msgstr "Numele noului nod"
+
+msgctxt "#30405"
+msgid "Are you sure you want to delete this rule?"
+msgstr "Sigur doriți să ștergeți această regulă?"
diff --git a/plugin.library.node.editor/resources/language/Russian/strings.po b/plugin.library.node.editor/resources/language/Russian/strings.po
new file mode 100644
index 0000000..15fbc11
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Russian/strings.po
@@ -0,0 +1,81 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Russian (http://www.transifex.com/projects/p/xbmc-addons/language/ru/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ru\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Библиотека видео"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Музыкальная медиатека"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Удалить"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Изменить название"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Изменить иконку"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Найти значок"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Содержимое"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Путь"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Правило"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Значение"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Содержимое"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Группа"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Путь"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Иконка"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Упорядочить по"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Направление"
diff --git a/plugin.library.node.editor/resources/language/Serbian (Cyrillic)/strings.po b/plugin.library.node.editor/resources/language/Serbian (Cyrillic)/strings.po
new file mode 100644
index 0000000..0bd648e
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Serbian (Cyrillic)/strings.po
@@ -0,0 +1,37 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Serbian (Cyrillic) (http://www.transifex.com/projects/p/xbmc-addons/language/sr_RS/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sr_RS\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Избриши"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Уреди натпис"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Путања"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Путања"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Сложи по"
diff --git a/plugin.library.node.editor/resources/language/Serbian/strings.po b/plugin.library.node.editor/resources/language/Serbian/strings.po
new file mode 100644
index 0000000..c03c966
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Serbian/strings.po
@@ -0,0 +1,41 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Serbian (http://www.transifex.com/projects/p/xbmc-addons/language/sr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sr\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Izbriši"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Uredi natpis"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Putanja"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikone"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Složi po"
diff --git a/plugin.library.node.editor/resources/language/Slovak/strings.po b/plugin.library.node.editor/resources/language/Slovak/strings.po
new file mode 100644
index 0000000..ad3dfe2
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Slovak/strings.po
@@ -0,0 +1,53 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Slovak (http://www.transifex.com/projects/p/xbmc-addons/language/sk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sk\n"
+"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Hudobná knižnica"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Vymazať"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Upraviť názov"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Nájsť cestu k logu"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Umiestnenie"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Skupina"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Umiestnenie"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Usporiadať podľa"
diff --git a/plugin.library.node.editor/resources/language/Slovenian/strings.po b/plugin.library.node.editor/resources/language/Slovenian/strings.po
new file mode 100644
index 0000000..dfef335
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Slovenian/strings.po
@@ -0,0 +1,61 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Slovenian (http://www.transifex.com/projects/p/xbmc-addons/language/sl/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sl\n"
+"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Izbriši"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Uredi oznako"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Prebrskajte za ikono"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Pot"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Pravilo"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Polje"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Vrednost"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Skupina"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Pot"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikona"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Razvrščeno po"
diff --git a/plugin.library.node.editor/resources/language/Spanish (Argentina)/strings.po b/plugin.library.node.editor/resources/language/Spanish (Argentina)/strings.po
new file mode 100644
index 0000000..79f65b7
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Spanish (Argentina)/strings.po
@@ -0,0 +1,57 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Spanish (Argentina) (http://www.transifex.com/projects/p/xbmc-addons/language/es_AR/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: es_AR\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Colección de Video"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Colección de Música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Eliminar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Buscar un icono"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ícono"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenar por"
diff --git a/plugin.library.node.editor/resources/language/Spanish (Mexico)/strings.po b/plugin.library.node.editor/resources/language/Spanish (Mexico)/strings.po
new file mode 100644
index 0000000..4a84664
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Spanish (Mexico)/strings.po
@@ -0,0 +1,57 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Spanish (Mexico) (http://www.transifex.com/projects/p/xbmc-addons/language/es_MX/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: es_MX\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Biblioteca Vídeo"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteca de Música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Eliminar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Buscar ícono"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ícono"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenar por"
diff --git a/plugin.library.node.editor/resources/language/Spanish/strings.po b/plugin.library.node.editor/resources/language/Spanish/strings.po
new file mode 100644
index 0000000..6b4b7d1
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Spanish/strings.po
@@ -0,0 +1,81 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Spanish (http://www.transifex.com/projects/p/xbmc-addons/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"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Vídeoteca"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Biblioteca de Música"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Eliminar"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Editar etiqueta"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Buscar por icono"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Contenido"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Campo"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operador"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Valor"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Contenido"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupo"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Ruta"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Icono"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Ordenar por"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Dirección"
diff --git a/plugin.library.node.editor/resources/language/Swedish/strings.po b/plugin.library.node.editor/resources/language/Swedish/strings.po
new file mode 100644
index 0000000..ac5850a
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Swedish/strings.po
@@ -0,0 +1,89 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Swedish (http://www.transifex.com/projects/p/xbmc-addons/language/sv/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: sv\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Videobibliotek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Musikbibliotek"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Ta bort"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Ändra namn"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Redigera ikon"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Bläddra bland ikoner"
+
+msgctxt "#30200"
+msgid "Content"
+msgstr "Innehåll"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Sökväg"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Regel"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Fält"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "Operatör"
+
+msgctxt "#30307"
+msgid "Value"
+msgstr "Värde"
+
+msgctxt "#30309"
+msgid "Content"
+msgstr "Innehåll"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grupp"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Sökväg"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Ikon"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sortera efter"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Riktning"
diff --git a/plugin.library.node.editor/resources/language/Tamil (India)/strings.po b/plugin.library.node.editor/resources/language/Tamil (India)/strings.po
new file mode 100644
index 0000000..a7f7d30
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Tamil (India)/strings.po
@@ -0,0 +1,45 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Tamil (India) (http://www.transifex.com/projects/p/xbmc-addons/language/ta_IN/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: ta_IN\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "நீக்கு"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "சிட்டை திருத்து"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "உருவத்திற்காக உலாவுக"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "பாதை"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "குழு"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "பாதை"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "வரிசைபடி"
diff --git a/plugin.library.node.editor/resources/language/Thai/strings.po b/plugin.library.node.editor/resources/language/Thai/strings.po
new file mode 100644
index 0000000..4457842
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Thai/strings.po
@@ -0,0 +1,57 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Thai (http://www.transifex.com/projects/p/xbmc-addons/language/th/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: th\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "แฟ้ม วิดีโอ"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "คลังเพลง"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "ลบ"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "แก้ป้ายชื่อ"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "เรียกดูไอคอน"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "เส้นทาง"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "กลุ่ม"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "เส้นทาง"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "ไอคอน"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "เรียงลำดับตาม"
diff --git a/plugin.library.node.editor/resources/language/Turkish/strings.po b/plugin.library.node.editor/resources/language/Turkish/strings.po
new file mode 100644
index 0000000..41ae4a1
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Turkish/strings.po
@@ -0,0 +1,77 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Turkish (http://www.transifex.com/projects/p/xbmc-addons/language/tr/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: tr\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Video Kitaplığı"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Müzik Kitaplığı"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Sil"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Etiketi düzenle"
+
+msgctxt "#30102"
+msgid "Edit icon"
+msgstr "Simgeyi Düzenle"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Simgeye gözat"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Yol"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Kural"
+
+msgctxt "#30305"
+msgid "Field"
+msgstr "Alan"
+
+msgctxt "#30306"
+msgid "Operator"
+msgstr "İşletici"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grup"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Yol"
+
+msgctxt "#30313"
+msgid "Icon"
+msgstr "Simge"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Sırala"
+
+msgctxt "#30315"
+msgid "Direction"
+msgstr "Yön"
diff --git a/plugin.library.node.editor/resources/language/Ukrainian/strings.po b/plugin.library.node.editor/resources/language/Ukrainian/strings.po
new file mode 100644
index 0000000..e02c760
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Ukrainian/strings.po
@@ -0,0 +1,53 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Ukrainian (http://www.transifex.com/projects/p/xbmc-addons/language/uk/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: uk\n"
+"Plural-Forms: nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Бібліотека відео"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Бібліотека музики"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Видалити"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Змінити назву"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Вибрати значок"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Шлях"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Група"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Шлях"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Упорядкувати за"
diff --git a/plugin.library.node.editor/resources/language/Uzbek/strings.po b/plugin.library.node.editor/resources/language/Uzbek/strings.po
new file mode 100644
index 0000000..8d28b24
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Uzbek/strings.po
@@ -0,0 +1,33 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Uzbek (http://www.transifex.com/projects/p/xbmc-addons/language/uz/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: uz\n"
+"Plural-Forms: nplurals=1; plural=0;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "O'chirish"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Yo'l"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Guruh"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Yo'l"
diff --git a/plugin.library.node.editor/resources/language/Vietnamese/strings.po b/plugin.library.node.editor/resources/language/Vietnamese/strings.po
new file mode 100644
index 0000000..310b376
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Vietnamese/strings.po
@@ -0,0 +1,37 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Vietnamese (http://www.transifex.com/projects/p/xbmc-addons/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"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Xóa"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Nhãn sửa"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Đường dẫn"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Nhóm"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Đường dẫn"
diff --git a/plugin.library.node.editor/resources/language/Welsh/strings.po b/plugin.library.node.editor/resources/language/Welsh/strings.po
new file mode 100644
index 0000000..40c497c
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Welsh/strings.po
@@ -0,0 +1,49 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Welsh (http://www.transifex.com/projects/p/xbmc-addons/language/cy/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: cy\n"
+"Plural-Forms: nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;\n"
+
+msgctxt "#30100"
+msgid "Delete"
+msgstr "Dileu"
+
+msgctxt "#30101"
+msgid "Edit label"
+msgstr "Golygu labeli"
+
+msgctxt "#30103"
+msgid "Browse for icon"
+msgstr "Pori am eiconau"
+
+msgctxt "#30204"
+msgid "Path"
+msgstr "Llwybr"
+
+msgctxt "#30205"
+msgid "Rule"
+msgstr "Rheol"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Grŵp"
+
+msgctxt "#30312"
+msgid "Path"
+msgstr "Llwybr"
+
+msgctxt "#30314"
+msgid "Order by"
+msgstr "Trefnu yn ôl"
diff --git a/plugin.library.node.editor/resources/language/Western Frisian/strings.po b/plugin.library.node.editor/resources/language/Western Frisian/strings.po
new file mode 100644
index 0000000..8a8b3f5
--- /dev/null
+++ b/plugin.library.node.editor/resources/language/Western Frisian/strings.po
@@ -0,0 +1,29 @@
+# Kodi Media Center language file
+# Addon Name: Library Node Editor
+# Addon id: plugin.library.node.editor
+# Addon Provider: Unfledged, Team-Kodi
+msgid ""
+msgstr ""
+"Project-Id-Version: XBMC Addons\n"
+"Report-Msgid-Bugs-To: alanwww1@xbmc.org\n"
+"POT-Creation-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
+"Last-Translator: Kodi Translation Team\n"
+"Language-Team: Western Frisian (http://www.transifex.com/projects/p/xbmc-addons/language/fy/)\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Language: fy\n"
+"Plural-Forms: nplurals=2; plural=(n != 1);\n"
+
+msgctxt "#30091"
+msgid "Video Library"
+msgstr "Fideobibleteek"
+
+msgctxt "#30092"
+msgid "Music Library"
+msgstr "Muzykbibleteek"
+
+msgctxt "#30310"
+msgid "Group"
+msgstr "Groep"
diff --git a/plugin.library.node.editor/resources/lib/orderby.py b/plugin.library.node.editor/resources/lib/orderby.py
new file mode 100755
index 0000000..686503c
--- /dev/null
+++ b/plugin.library.node.editor/resources/lib/orderby.py
@@ -0,0 +1,209 @@
+# coding=utf-8
+import os, sys
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
+import xml.etree.ElementTree as xmltree
+import urllib
+from traceback import print_exc
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+ADDONVERSION = ADDON.getAddonInfo('version')
+KODIVERSION = xbmc.getInfoLabel( "System.BuildVersion" ).split(".")[0]
+LANGUAGE = ADDON.getLocalizedString
+CWD = ADDON.getAddonInfo('path').decode("utf-8")
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+DEFAULTPATH = xbmc.translatePath( os.path.join( CWD, 'resources' ).encode("utf-8") ).decode("utf-8")
+ltype = sys.modules[ '__main__' ].ltype
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+class OrderByFunctions():
+ def __init__(self):
+ pass
+
+ def _load_rules( self ):
+ if ltype == 'video':
+ overridepath = os.path.join( DEFAULTPATH , "videorules.xml" )
+ else:
+ overridepath = os.path.join( DEFAULTPATH , "musicrules.xml" )
+ try:
+ tree = xmltree.parse( overridepath )
+ return tree
+ except:
+ return None
+
+ def translateOrderBy( self, rule ):
+ # Load the rules
+ tree = self._load_rules()
+ hasValue = True
+ if rule[ 0 ] == "sorttitle":
+ rule[ 0 ] = "title"
+ if rule[ 0 ] != "random":
+ # Get the field we're ordering by
+ elems = tree.getroot().find( "matches" ).findall( "match" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == rule[ 0 ]:
+ match = xbmc.getLocalizedString( int( elem.find( "label" ).text ) )
+ else:
+ # We'll manually set for random
+ match = xbmc.getLocalizedString( 590 )
+ # Get localization of direction
+ direction = None
+ elems = tree.getroot().find( "orderby" ).findall( "type" )
+ for elem in elems:
+ if elem.text == rule[ 1 ]:
+ direction = xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) )
+ directionVal = rule[ 1 ]
+ if direction is None:
+ direction = xbmc.getLocalizedString( int( tree.getroot().find( "orderby" ).find( "type" ).attrib.get( "label" ) ) )
+ directionVal = tree.getroot().find( "orderby" ).find( "type" ).text
+ return [ [ match, rule[ 0 ] ], [ direction, directionVal ] ]
+
+ def displayOrderBy( self, actionPath ):
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the content type
+ content = root.find( "content" ).text
+ # Get the order node
+ orderby = root.find( "order" )
+ if orderby is None:
+ # There is no orderby element, so add one
+ self.newOrderBy( tree, actionPath )
+ orderby = root.find( "order" )
+ match = orderby.text
+ if "direction" in orderby.attrib:
+ direction = orderby.attrib.get( "direction" )
+ else:
+ direction = ""
+ translated = self.translateOrderBy( [match, direction ] )
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 0 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editOrderBy&actionPath=" % ltype + actionPath + "&content=" + content + "&default=" + translated[ 0 ][ 1 ]
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 1 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editOrderByDirection&actionPath=" % ltype + actionPath + "&default=" + translated[ 1 ][ 1 ]
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ except:
+ print_exc()
+
+ def editOrderBy( self, actionPath, content, default ):
+ # Load all operator groups
+ tree = self._load_rules().getroot()
+ elems = tree.find( "matches" ).findall( "match" )
+ selectName = []
+ selectValue = []
+ # Find the matches for the content we've been passed
+ for elem in elems:
+ contentMatch = elem.find( content )
+ if contentMatch is not None:
+ selectName.append( xbmc.getLocalizedString( int( elem.find( "label" ).text ) ) )
+ selectValue.append( elem.attrib.get( "name" ) )
+ # Add a random element
+ selectName.append( xbmc.getLocalizedString( 590 ) )
+ selectValue.append( "random" )
+ # Let the user select an operator
+ selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30314 ), selectName )
+ # If the user selected no operator...
+ if selectedOperator == -1:
+ return
+ returnVal = selectValue[ selectedOperator ]
+ if returnVal == "title":
+ returnVal = "sorttitle"
+ self.writeUpdatedOrderBy( actionPath, field = returnVal )
+
+ def editDirection( self, actionPath, direction ):
+ # Load all directions
+ tree = self._load_rules().getroot()
+ elems = tree.find( "orderby" ).findall( "type" )
+ selectName = []
+ selectValue = []
+ # Find the group we've been passed and load its operators
+ for elem in elems:
+ selectName.append( xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) ) )
+ selectValue.append( elem.text )
+ # Let the user select an operator
+ selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30315 ), selectName )
+ # If the user selected no operator...
+ if selectedOperator == -1:
+ return
+ self.writeUpdatedOrderBy( actionPath, direction = selectValue[ selectedOperator ] )
+
+ def writeUpdatedOrderBy( self, actionPath, field = None, direction = None ):
+ # This function writes an updated orderby rule
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get all the rules
+ orderby = root.find( "order" )
+ if field is not None:
+ orderby.text = field
+ if direction is not None:
+ orderby.set( "direction", direction )
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def newOrderBy( self, tree, actionPath ):
+ # This function adds a new OrderBy, with default match and direction
+ try:
+ # Load the xml file
+ #tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the content type
+ content = root.find( "content" )
+ if content is None:
+ xbmcgui.Dialog().ok( ADDONNAME, LANGUAGE( 30406 ) )
+ return
+ else:
+ content = content.text
+ # Find the default match for this content type
+ ruleTree = self._load_rules().getroot()
+ elems = ruleTree.find( "matches" ).findall( "match" )
+ match = "title"
+ for elem in elems:
+ contentCheck = elem.find( content )
+ if contentCheck is not None:
+ # We've found the first match for this type
+ match = elem.attrib.get( "name" )
+ break
+ if match == "title":
+ match = "sorttitle"
+ # Find the default direction
+ elem = ruleTree.find( "orderby" ).find( "type" )
+ direction = elem.text
+ # Write the new rule
+ newRule = xmltree.SubElement( root, "order" )
+ newRule.text = match
+ newRule.set( "direction", direction )
+ # Save the file
+ self.indent( root )
+ tree.write( urllib.unquote( actionPath ), encoding="UTF-8" )
+ except:
+ print_exc()
+
+ # in-place prettyprint formatter
+ def indent( self, elem, level=0 ):
+ i = "\n" + level*"\t"
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + "\t"
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ self.indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+
diff --git a/plugin.library.node.editor/resources/lib/pathrules.py b/plugin.library.node.editor/resources/lib/pathrules.py
new file mode 100644
index 0000000..93b5ef3
--- /dev/null
+++ b/plugin.library.node.editor/resources/lib/pathrules.py
@@ -0,0 +1,391 @@
+# coding=utf-8
+import os, sys, shutil
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
+import xml.etree.ElementTree as xmltree
+import urllib
+from traceback import print_exc
+import json
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+ADDONVERSION = ADDON.getAddonInfo('version')
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+LANGUAGE = ADDON.getLocalizedString
+CWD = ADDON.getAddonInfo('path').decode("utf-8")
+DEFAULTPATH = xbmc.translatePath( os.path.join( CWD, 'resources' ).encode("utf-8") ).decode("utf-8")
+DATAPATH = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')).decode('utf-8')
+ltype = sys.modules[ '__main__' ].ltype
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+class PathRuleFunctions():
+ def __init__(self):
+ self.nodeRules = None
+ self.ATTRIB = None
+
+ def _load_rules( self ):
+ if ltype == 'video':
+ overridepath = os.path.join( DEFAULTPATH , "videorules.xml" )
+ else:
+ overridepath = os.path.join( DEFAULTPATH , "musicrules.xml" )
+ try:
+ tree = xmltree.parse( overridepath )
+ return tree
+ except:
+ return None
+
+ def translateComponent( self, component, splitPath ):
+ if component[ 0 ] is None:
+ return splitPath[ 0 ]
+
+ if unicode( component[ 0 ], "utf-8" ).isnumeric():
+ string = LANGUAGE( int( component[ 0 ] ) )
+ if string != "": return string
+ return xbmc.getLocalizedString( int( component[ 0 ] ) )
+ else:
+ return component[ 0 ]
+
+ def translateValue( self, rule, splitPath, ruleNum ):
+ if splitPath[ ruleNum ][ 1 ] == "":
+ return "<No value>"
+
+ if rule[ 1 ] == "year" or rule[ 2 ] != "integer" or rule[ 3 ] is None:
+ return splitPath[ ruleNum ][ 1 ]
+
+ try:
+ value = int( splitPath[ ruleNum ][ 1 ] )
+ except:
+ return splitPath[ ruleNum ][ 1 ]
+
+ json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Files.GetDirectory", "params": { "properties": ["title"], "directory": "%s", "media": "files" } }' % rule[ 3 ] )
+ json_query = unicode(json_query, 'utf-8', errors='ignore')
+ json_response = json.loads(json_query)
+ listings = []
+ values = []
+ # Add all directories returned by the json query
+ if json_response.has_key('result') and json_response['result'].has_key('files') and json_response['result']['files'] is not None:
+ for item in json_response['result']['files']:
+ if "id" in item and item[ "id" ] == value:
+ return "(%d) %s" %( value, item[ "label" ] )
+
+ # Didn't find a match
+ return "%s (%s)" %( splitPath[ ruleNum ][ 1 ], xbmc.getLocalizedString(13205) )
+
+ def displayRule( self, actionPath, ruleNum ):
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the path
+ path = root.find( "path" ).text
+ # Split the path element
+ splitPath = self.ATTRIB.splitPath( path )
+ # Get the rules
+ rules = self.getRulesForPath( splitPath[ 0 ] )
+ if len( splitPath ) == int( ruleNum ):
+ # This rule doesn't exist - create it
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, rules[ 0 ][ 1 ], "" ) )
+ rule = rules[ 0 ]
+ translatedValue = "<No value>"
+ else:
+ # Find the matching rule
+ rule = self.getMatchingRule( splitPath[ ruleNum ], rules )
+ translatedValue = self.translateValue( rule, splitPath, ruleNum )
+
+ #Component
+ listitem = xbmcgui.ListItem( label="%s" % ( self.translateComponent( rule, splitPath[ ruleNum ] ) ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editPathMatch&actionPath=%s&rule=%d" %( ltype, actionPath, ruleNum )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ # Value
+ listitem = xbmcgui.ListItem( label="%s" % ( translatedValue ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editPathValue&actionPath=%s&rule=%s" %( ltype, actionPath, ruleNum )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ # Browse
+ if rule[ 3 ] is not None:
+ listitem = xbmcgui.ListItem( label=LANGUAGE(30107) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=browsePathValue&actionPath=%s&rule=%s" %( ltype, actionPath, ruleNum )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ return
+ except:
+ log( "Failed" )
+ print_exc()
+
+ def getRulesForPath( self, path ):
+ # This function gets all valid rules for a given path
+
+ # Load the rules
+ tree = self._load_rules()
+ subSearch = None
+ content = []
+ elems = tree.getroot().find( "paths" ).findall( "type" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == path[ 0 ]:
+ for contentType in elem.findall( "content" ):
+ content.append( contentType.text )
+ subSearch = elem
+ break
+
+ if path[ 1 ] and subSearch is not None:
+ for elem in subSearch.findall( "type" ):
+ if elem.attrib.get( "name" ) == path[ 1 ]:
+ if elem.find( "content" ):
+ content = []
+ for contentType in elem.findall( "content" ):
+ content.append( contentType.text )
+ break
+
+ rules = []
+ for rule in tree.getroot().find( "pathRules" ).findall( "rule" ):
+ # Can it be browsed
+ if rule.find( "browse" ) is not None:
+ browse = rule.find( "browse" ).text
+ else:
+ browse = None
+ if len( content ) == 0:
+ rules.append( ( rule.attrib.get( "label" ), rule.attrib.get( "name" ), rule.find( "value" ).text, browse ) )
+ else:
+ for contentType in rule.findall( "content" ):
+ if contentType.text in content:
+ # If the root of the browse is changed dependant on what we're looking at, replace
+ # it now with the correct content
+ if browse is not None and "::root::" in browse:
+ browse = browse.replace( "::root::", content[ 0 ] )
+ rules.append( ( rule.attrib.get( "label" ), rule.attrib.get( "name" ), rule.find( "value" ).text, browse ) )
+
+ if len( rules ) == 0:
+ return [ ( None, "property", "string", None ) ]
+ return rules
+
+ def getMatchingRule( self, component, rules ):
+ # This function matches a component to its rule
+ for rule in rules:
+ if rule[ 1 ] == component[ 0 ]:
+ return rule
+
+ # No rule matched, return an empty one
+ return ( None, "property", "string", None )
+
+ def editMatch( self, actionPath, ruleNum ):
+ # Change the match element of a path component
+
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the path
+ path = root.find( "path" ).text
+ # Split the path element
+ splitPath = self.ATTRIB.splitPath( path )
+ # Get the rules and current value
+ rules = self.getRulesForPath( splitPath[ 0 ] )
+ currentValue = splitPath[ ruleNum ][ 1 ]
+
+ if rules[ 0 ][ 0 ] is None:
+ # There are no available choices
+ self.manuallyEditMatch( actionPath, ruleNum, splitPath[ ruleNum ][ 0 ], currentValue )
+ return
+
+ # Build list of rules to choose from
+ selectName = []
+ for rule in rules:
+ selectName.append( self.translateComponent( rule, None ) )
+
+ # Add a manual option
+ selectName.append( LANGUAGE( 30408 ) )
+
+ # Let the user select an operator
+ selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30305 ), selectName )
+ # If the user selected no operator...
+ if selectedOperator == -1:
+ return
+ elif selectedOperator == len( rules ):
+ # User choose custom property
+ self.manuallyEditMatch( actionPath, ruleNum, splitPath[ ruleNum ][ 0 ], currentValue )
+ return
+ else:
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, rules[ selectedOperator ][ 1 ], currentValue ) )
+
+ def manuallyEditMatch( self, actionPath, ruleNum, currentName, currentValue ):
+ type = xbmcgui.INPUT_ALPHANUM
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30318 ), currentName, type=type )
+ if returnVal != "":
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, returnVal.decode( "utf-8" ), currentValue ) )
+
+ def editValue( self, actionPath, ruleNum ):
+ # Let the user edit the value of a path component
+
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the path
+ path = root.find( "path" ).text
+ # Split the path element
+ splitPath = self.ATTRIB.splitPath( path )
+ # Get the rules and current value
+ rules = self.getRulesForPath( splitPath[ 0 ] )
+ rule = self.getMatchingRule( splitPath[ ruleNum ], rules )
+
+ if rule[ 2 ] == "boolean":
+ # Let the user select a boolean
+ selectedBool = xbmcgui.Dialog().select( LANGUAGE( 30307 ), [ xbmc.getLocalizedString(20122), xbmc.getLocalizedString(20424) ] )
+ # If the user selected nothing...
+ if selectedBool == -1:
+ return
+ value = "true"
+ if selectedBool == 1:
+ value = "false"
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, splitPath[ ruleNum][ 0 ], value ) )
+ else:
+ type = xbmcgui.INPUT_ALPHANUM
+ if rule[ 2 ] == "integer":
+ type = xbmcgui.INPUT_NUMERIC
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30307 ), splitPath[ ruleNum ][ 1 ], type=type )
+ if returnVal != "":
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, splitPath[ ruleNum ][ 0 ], returnVal.decode( "utf-8" ) ) )
+
+
+ def browse( self, actionPath, ruleNum ):
+ # This function launches the browser for the given property type
+
+ pDialog = xbmcgui.DialogProgress()
+ pDialog.create( ADDONNAME, LANGUAGE( 30317 ) )
+
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the path
+ path = root.find( "path" ).text
+ # Split the path element
+ splitPath = self.ATTRIB.splitPath( path )
+ # Get the rules and current value
+ rules = self.getRulesForPath( splitPath[ 0 ] )
+ rule = self.getMatchingRule( splitPath[ ruleNum ], rules )
+ title = self.translateComponent( rule, splitPath[ ruleNum ] )
+
+ # Get the path we'll be browsing
+ browsePath = self.getBrowsePath( splitPath, rule[ 3 ], ruleNum )
+
+ json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Files.GetDirectory", "params": { "properties": ["title", "file", "thumbnail"], "directory": "%s", "media": "files" } }' % browsePath )
+ json_query = unicode(json_query, 'utf-8', errors='ignore')
+ json_response = json.loads(json_query)
+ listings = []
+ values = []
+ # Add all directories returned by the json query
+ if json_response.has_key('result') and json_response['result'].has_key('files') and json_response['result']['files'] is not None:
+ total = len( json_response[ 'result' ][ 'files' ] )
+ for item in json_response['result']['files']:
+ if item[ "label" ] == "..":
+ continue
+ thumb = None
+ if item[ "thumbnail" ] is not "":
+ thumb = item[ "thumbnail" ]
+ listitem = xbmcgui.ListItem(label=item[ "label" ], iconImage=thumb )
+ listitem.setProperty( "thumbnail", thumb )
+ listings.append( listitem )
+ if rule[ 2 ] == "integer" and "id" in item:
+ values.append( str( item[ "id" ] ) )
+ else:
+ values.append( item[ "label" ] )
+
+ pDialog.close()
+
+ if len( listings ) == 0:
+ # No browsable options found
+ xbmcgui.Dialog().ok( ADDONNAME, LANGUAGE( 30409 ) )
+ return
+
+ # Show dialog
+ w = ShowDialog( "DialogSelect.xml", CWD, listing=listings, windowtitle=title )
+ w.doModal()
+ selectedItem = w.result
+ del w
+ if selectedItem == "" or selectedItem == -1:
+ return None
+
+ self.ATTRIB.writeUpdatedPath( actionPath, ( ruleNum, splitPath[ ruleNum ][ 0 ], values[ selectedItem ] ) )
+
+ def getBrowsePath( self, splitPath, newBase, rule ):
+ # This function replaces the base path with the browse path, and removes the current
+ # component
+
+ returnText = ""
+
+ if "::root::" in newBase:
+ newBase = newBase.replace( "::root::", splitPath[ 0 ][ 0 ] )
+
+ # Enumarate through everything in the existing path
+ addedQ = False
+ for x, component in enumerate( splitPath ):
+ if x != rule:
+ # Transfer this component to the new path
+ if x == 0:
+ returnText = newBase
+ elif not addedQ:
+ returnText += "?%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ addedQ = True
+ else:
+ returnText += "&%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ return returnText
+
+ # in-place prettyprint formatter
+ def indent( self, elem, level=0 ):
+ i = "\n" + level*"\t"
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + "\t"
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ self.indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+
+# ============================
+# === PRETTY SELECT DIALOG ===
+# ============================
+class ShowDialog( xbmcgui.WindowXMLDialog ):
+ def __init__( self, *args, **kwargs ):
+ xbmcgui.WindowXMLDialog.__init__( self )
+ self.listing = kwargs.get( "listing" )
+ self.windowtitle = kwargs.get( "windowtitle" )
+ self.result = -1
+
+ def onInit(self):
+ try:
+ self.fav_list = self.getControl(6)
+ self.getControl(3).setVisible(False)
+ except:
+ print_exc()
+ self.fav_list = self.getControl(3)
+ self.getControl(5).setVisible(False)
+ self.getControl(1).setLabel(self.windowtitle)
+ for item in self.listing :
+ listitem = xbmcgui.ListItem(label=item.getLabel(), label2=item.getLabel2(), iconImage=item.getProperty( "icon" ), thumbnailImage=item.getProperty( "thumbnail" ))
+ listitem.setProperty( "Addon.Summary", item.getLabel2() )
+ self.fav_list.addItem( listitem )
+ self.setFocus(self.fav_list)
+
+ def onAction(self, action):
+ if action.getId() in ( 9, 10, 92, 216, 247, 257, 275, 61467, 61448, ):
+ self.result = -1
+ self.close()
+
+ def onClick(self, controlID):
+ if controlID == 6 or controlID == 3:
+ num = self.fav_list.getSelectedPosition()
+ self.result = num
+ else:
+ self.result = -1
+ self.close()
+
+ def onFocus(self, controlID):
+ pass
diff --git a/plugin.library.node.editor/resources/lib/pluginBrowser.py b/plugin.library.node.editor/resources/lib/pluginBrowser.py
new file mode 100644
index 0000000..fa57388
--- /dev/null
+++ b/plugin.library.node.editor/resources/lib/pluginBrowser.py
@@ -0,0 +1,65 @@
+# coding=utf-8
+import sys
+import xbmc, xbmcaddon, xbmcgui
+import json
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+LANGUAGE = ADDON.getLocalizedString
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+ltype = sys.modules[ '__main__' ].ltype
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+def getPluginPath( location = None ):
+ listings = []
+ listingsLabels = []
+
+ if location is not None:
+ # If location given, add 'create' item
+ listings.append( "::CREATE::" )
+ listingsLabels.append( LANGUAGE( 30411 ) )
+ else:
+ # If no location, build default
+ if location is None:
+ if ltype == "video":
+ location = "addons://sources/video"
+ else:
+ location = "addons://sources/audio"
+
+ # Show a waiting dialog, then get the listings for the directory
+ dialog = xbmcgui.DialogProgress()
+ dialog.create( ADDONNAME, LANGUAGE( 30410 ) )
+
+ json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Files.GetDirectory", "params": { "properties": ["title", "file", "thumbnail", "episode", "showtitle", "season", "album", "artist", "imdbnumber", "firstaired", "mpaa", "trailer", "studio", "art"], "directory": "' + location + '", "media": "files" } }')
+ json_query = unicode(json_query, 'utf-8', errors='ignore')
+ json_response = json.loads(json_query)
+
+ # Add all directories returned by the json query
+ if json_response.has_key('result') and json_response['result'].has_key('files') and json_response['result']['files']:
+ json_result = json_response['result']['files']
+
+ for item in json_result:
+ if item[ "file" ].startswith( "plugin://" ):
+ listings.append( item[ "file" ] )
+ listingsLabels.append( "%s >" %( item[ "label" ] ) )
+
+ # Close progress dialog
+ dialog.close()
+
+ selectedItem = xbmcgui.Dialog().select( LANGUAGE( 30309 ), listingsLabels )
+
+ if selectedItem == -1:
+ # User cancelled
+ return None
+
+ selectedAction = listings[ selectedItem ]
+ if selectedAction == "::CREATE::":
+ return location
+ else:
+ # User has chosen a sub-level to display, add details and re-call this function
+ return getPluginPath( selectedAction )
diff --git a/plugin.library.node.editor/resources/lib/rules.py b/plugin.library.node.editor/resources/lib/rules.py
new file mode 100755
index 0000000..b77a33a
--- /dev/null
+++ b/plugin.library.node.editor/resources/lib/rules.py
@@ -0,0 +1,1107 @@
+# coding=utf-8
+import os, sys, shutil
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
+import xml.etree.ElementTree as xmltree
+import urllib
+from traceback import print_exc
+import json
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+ADDONVERSION = ADDON.getAddonInfo('version')
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+LANGUAGE = ADDON.getLocalizedString
+CWD = ADDON.getAddonInfo('path').decode("utf-8")
+DEFAULTPATH = xbmc.translatePath( os.path.join( CWD, 'resources' ).encode("utf-8") ).decode("utf-8")
+DATAPATH = xbmc.translatePath(xbmcaddon.Addon().getAddonInfo('profile')).decode('utf-8')
+ltype = sys.modules[ '__main__' ].ltype
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+class RuleFunctions():
+ def __init__(self):
+ self.nodeRules = None
+
+ def _load_rules( self ):
+ if ltype == 'video':
+ overridepath = os.path.join( DEFAULTPATH , "videorules.xml" )
+ else:
+ overridepath = os.path.join( DEFAULTPATH , "musicrules.xml" )
+ try:
+ tree = xmltree.parse( overridepath )
+ return tree
+ except:
+ return None
+
+ def translateRule( self, rule ):
+ # Load the rules
+ tree = self._load_rules()
+ hasValue = True
+ elems = tree.getroot().find( "matches" ).findall( "match" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == rule[ 0 ]:
+ match = xbmc.getLocalizedString( int( elem.find( "label" ).text ) )
+ group = elem.find( "operator" ).text
+ elems = tree.getroot().find( "operators" ).findall( "group" )
+ operator = None
+ defaultOperator = None
+ defaultOperatorValue = None
+ for elem in elems:
+ if elem.attrib.get( "name" ) == group:
+ for operators in elem.findall( "operator" ):
+ if operators.text == rule[ 1 ]:
+ operator = xbmc.getLocalizedString( int( operators.attrib.get( "label" ) ) )
+ if defaultOperator is None:
+ defaultOperator = xbmc.getLocalizedString( int( operators.attrib.get( "label" ) ) )
+ defaultOperatorValue = operators.text
+ if "option" in elem.attrib:
+ hasValue = False
+ # If we didn't match an operator, set it to the default
+ if operator is None:
+ operator = defaultOperator
+ rule[ 1 ] = defaultOperatorValue
+ if hasValue == False:
+ return [ [ match, rule[ 0 ] ], [ operator, group, rule[ 1 ] ], [ "|NONE|", "<No value>" ] ]
+ if len( rule ) == 2 or rule[ 2 ] == "" or rule[ 2 ] is None:
+ return [ [ match, rule[ 0 ] ], [ operator, group, rule[ 1 ] ], [ "", "<No value>" ] ]
+ return [ [ match, rule[ 0 ] ], [ operator, group, rule[ 1 ] ], [ rule[ 2 ], rule[ 2 ] ] ]
+
+ def displayRule( self, actionPath, path, ruleNum ):
+ if actionPath.endswith( "index.xml" ):
+ # If this is a parent node, call alternative function
+ self.displayNodeRule( actionPath, ruleNum )
+ return
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ actionPath = actionPath
+ # Get the content type
+ content = root.find( "content" )
+ if content is not None:
+ content = content.text
+ else:
+ content = "NONE"
+ # Get all the rules
+ ruleCount = 0
+ rules = root.findall( "rule" )
+ if len( rules ) == int( ruleNum ):
+ # This rule doesn't exist - create it
+ self.newRule( tree, urllib.unquote( actionPath ) )
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ if str( ruleCount ) == ruleNum:
+ value = rule.find( "value" )
+ if value is None:
+ value = ""
+ else:
+ value = value.text
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value ] )
+ # Rule to change match
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 0 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editMatch&actionPath=" % ltype + actionPath + "&content=" + content + "&default=" + translated[ 0 ][ 1 ] + "&rule=" + str( ruleCount )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 1 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editOperator&actionPath=" % ltype + actionPath + "&group=" + translated[ 1 ][ 1 ] + "&default=" + translated[ 1 ][ 2 ] + "&rule=" + str( ruleCount )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ if not ( translated[ 2 ][ 0 ] ) == "|NONE|":
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 2 ][ 1 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ # Check if this match type can be browsed
+ if self.canBrowse( translated[ 0 ][ 1 ], content ):
+ #listitem.addContextMenuItems( [(LANGUAGE(30107), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount ) + "&match=" + translated[ 0 ][ 1 ] + "&content=" + content + ")" )], replaceItems = True )
+ listitem = xbmcgui.ListItem( label=LANGUAGE(30107) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=browseValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount ) + "&match=" + translated[ 0 ][ 1 ] + "&content=" + content
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ #self.browse( translated[ 0 ][ 1 ], content )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ return
+ ruleCount = ruleCount + 1
+ except:
+ print_exc()
+
+ def editMatch( self, actionPath, ruleNum, content, default ):
+ # Load all operator groups
+ tree = self._load_rules().getroot()
+ elems = tree.find( "matches" ).findall( "match" )
+ selectName = []
+ selectValue = []
+ # Find the matches for the content we've been passed
+ for elem in elems:
+ if content != "NONE":
+ contentMatch = elem.find( content )
+ if contentMatch is not None:
+ selectName.append( xbmc.getLocalizedString( int( elem.find( "label" ).text ) ) )
+ selectValue.append( elem.attrib.get( "name" ) )
+ else:
+ pass
+ else:
+ selectName.append( xbmc.getLocalizedString( int( elem.find( "label" ).text ) ) )
+ selectValue.append( elem.attrib.get( "name" ) )
+ # Let the user select an operator
+ selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30305 ), selectName )
+ # If the user selected no operator...
+ if selectedOperator == -1:
+ return
+ self.writeUpdatedRule( actionPath, ruleNum, match = selectValue[ selectedOperator ] )
+
+ def editOperator( self, actionPath, ruleNum, group, default ):
+ # Load all operator groups
+ tree = self._load_rules().getroot()
+ elems = tree.find( "operators" ).findall( "group" )
+ selectName = []
+ selectValue = []
+ # Find the group we've been passed and load its operators
+ for elem in elems:
+ if elem.attrib.get( "name" ) == group:
+ for operators in elem.findall( "operator" ):
+ selectName.append( xbmc.getLocalizedString( int( operators.attrib.get( "label" ) ) ) )
+ selectValue.append( operators.text )
+ # Let the user select an operator
+ selectedOperator = xbmcgui.Dialog().select( LANGUAGE( 30306 ), selectName )
+ # If the user selected no operator...
+ if selectedOperator == -1:
+ return
+ self.writeUpdatedRule( actionPath, ruleNum, operator = selectValue[ selectedOperator ] )
+
+ def editValue( self, actionPath, ruleNum ):
+ # This function is the entry point for editing the value of a rule
+ # Because we can't always pass the current value through the uri, we first need
+ # to retrieve it, and the operator data type
+ try:
+ if actionPath.endswith( "index.xml" ):
+ ( filePath, fileName ) = os.path.split( actionPath )
+ # Load the rules file
+ if ltype == 'video':
+ tree = xmltree.parse( os.path.join( DATAPATH, "videorules.xml" ) )
+ else:
+ tree = xmltree.parse( os.path.join( DATAPATH, "musicrules.xml" ) )
+ root = tree.getroot()
+ nodes = root.findall( "node" )
+ for node in nodes:
+ if node.attrib.get( "name" ) == filePath:
+ rules = node.findall( "rule" )
+ ruleCount = 0
+ for rule in rules:
+ if ruleCount == int( ruleNum ):
+ # This is the rule we'll be updating
+ # Get the current value
+ curValue = rule.find( "value" )
+ if curValue is None:
+ curValue = ""
+ else:
+ curValue = curValue.text
+ match = rule.attrib.get( "field" )
+ operator = rule.attrib.get( "operator" )
+ ruleCount += 1
+ else:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get all the rules
+ ruleCount = 0
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ if str( ruleCount ) == ruleNum:
+ # This is the rule we'll be updating
+ # Get the current value
+ curValue = rule.find( "value" )
+ if curValue is None:
+ curValue = ""
+ else:
+ curValue = curValue.text
+ match = rule.attrib.get( "field" )
+ operator = rule.attrib.get( "operator" )
+ ruleCount = ruleCount + 1
+ # Now, use the match value to get the group of operators this
+ # comes from (this will tell us the data type in all types
+ # but "date")
+ tree = self._load_rules().getroot()
+ elems = tree.find( "matches" ).findall( "match" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == match:
+ group = elem.find( "operator" ).text
+ if group == "date":
+ # We probably should go through the tree again, but we'll just check
+ # for string ending in "inthelast", and switch the type to numeric
+ if operator.endswith( "inthelast" ):
+ group = "numeric"
+ # Set the type of text entry dialog to be used
+ if group == "string":
+ type = xbmcgui.INPUT_ALPHANUM
+ if group == "numeric":
+ type = xbmcgui.INPUT_NUMERIC
+ if group == "time":
+ type = xbmcgui.INPUT_TIME
+ if group == "date":
+ type = xbmcgui.INPUT_DATE
+ if group == "isornot":
+ type = xbmcgui.INPUT_ALPHANUM
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30307 ), curValue, type=type )
+ if returnVal != "":
+ self.writeUpdatedRule( actionPath, ruleNum, value=returnVal.decode( "utf-8" ) )
+ except:
+ print_exc()
+
+ def writeUpdatedRule( self, actionPath, ruleNum, match = None, operator = None, value = None ):
+ # This function writes an updated match, operator or value to a rule
+ if actionPath.endswith( "index.xml" ):
+ # This is a parent node rule, so call the relevant function
+ #( filePath, fileName ) = os.path.split( actionPath )
+ #self.editNodeRule( filePath, originalRule, translated )
+ self.editNodeRule( actionPath, ruleNum, match, operator, value )
+ return
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get all the rules
+ ruleCount = 0
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ if str( ruleCount ) == ruleNum:
+ # This is the rule we're updating
+ valueElem = rule.find( "value" )
+ if match is None:
+ match = rule.attrib.get( "field" )
+ if operator is None:
+ operator = rule.attrib.get( "operator" )
+ if value is None:
+ if valueElem is None:
+ value = ""
+ else:
+ value = valueElem.text
+ if value is None:
+ value = ""
+ translated = self.translateRule( [ match, operator, value ] )
+ # Update the rule
+ rule.set( "field", translated[ 0 ][ 1 ] )
+ rule.set( "operator", translated[ 1 ][ 2 ] )
+ if len( translated ) == 3:
+ if rule.find( "value" ) == None:
+ # Create a new rule node
+ xmltree.SubElement( rule, "value" ).text = translated[ 2 ][ 0 ]
+ else:
+ rule.find( "value" ).text = translated[ 2 ][ 0 ]
+ ruleCount = ruleCount + 1
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def newRule( self, tree, actionPath ):
+ # This function adds a new rule, with default match and operator, no value
+ try:
+ # Load the xml file
+ # tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get the content type
+ content = root.find( "content" )
+ # Find the default match for this content type
+ ruleTree = self._load_rules().getroot()
+ elems = ruleTree.find( "matches" ).findall( "match" )
+ match = "title"
+ for elem in elems:
+ if content is not None:
+ contentCheck = elem.find( content.text )
+ if contentCheck is not None:
+ # We've found the first match for this type
+ match = elem.attrib.get( "name" )
+ operator = elem.find( "operator" ).text
+ break
+ else:
+ # We've found the first match for this type
+ match = elem.attrib.get( "name" )
+ operator = elem.find( "operator" ).text
+ break
+ # Find the default operator for this match
+ elems = ruleTree.find( "operators" ).findall( "group" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == operator:
+ operator = elem.find( "operator" ).text
+ break
+ # Write the new rule
+ newRule = xmltree.SubElement( root, "rule" )
+ newRule.set( "field", match )
+ newRule.set( "operator", operator )
+ xmltree.SubElement( newRule, "value" )
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ if actionPath.endswith( "index.xml" ):
+ ( filePath, fileName ) = os.path.split( actionPath )
+ newRule = self.translateRule( [ match, operator, "" ] )
+ self.addNodeRule( filePath, newRule )
+ except:
+ print_exc()
+
+ def deleteRule( self, actionPath, ruleNum ):
+ # This function deletes a rule
+ result = xbmcgui.Dialog().yesno(ADDONNAME, LANGUAGE( 30405 ) )
+ if not result:
+ return
+ if actionPath.endswith( "index.xml" ):
+ # This is a parent node rule, so call the relevant function
+ #( filePath, fileName ) = os.path.split( actionPath )
+ #self.deleteNodeRule( filePath, originalRule )
+ self.deleteNodeRule( actionPath, ruleNum )
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Get all the rules
+ ruleCount = 0
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ if str( ruleCount ) == ruleNum:
+ # This is the rule we want to delete
+ if actionPath.endswith( "index.xml" ):
+ # Translate the rule, so we can delete it from the views
+ valueElem = rule.find( "value" )
+ origMatch = rule.attrib.get( "field" )
+ origOperator = rule.attrib.get( "operator" )
+ if valueElem is None:
+ origValue = ""
+ else:
+ origValue = valueElem.text
+ originalRule = self.translateRule( [ origMatch, origOperator, origValue ] )
+ # Delete the rule
+ root.remove( rule )
+ break
+ ruleCount = ruleCount + 1
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ # Functions for managing rules in all views
+ def displayNodeRule( self, actionPath, ruleNum ):
+ # This function will load and display a parent node rule
+ # (and create one, if the ruleNum specified doesn't exist)
+ # Split the actionPath, to make things easier
+ ( filePath, fileName ) = os.path.split( actionPath )
+ try:
+ # Load the rules file
+ if ltype == 'video':
+ tree = xmltree.parse( os.path.join( DATAPATH, "videorules.xml" ) )
+ else:
+ tree = xmltree.parse( os.path.join( DATAPATH, "musicrules.xml" ) )
+ root = tree.getroot()
+ # Find the relevant node
+ nodes = root.findall( "node" )
+ if nodes is None:
+ self.newNodeRule( actionPath, ruleNum )
+ return
+ ruleNode = None
+ for node in nodes:
+ if node.attrib.get( "name" ) == filePath:
+ ruleNode = node
+ break
+ if ruleNode == None:
+ self.newNodeRule( actionPath, ruleNum )
+ return
+ # Find the relevant rule
+ rules = node.findall( "rule" )
+ if rules is None or len( rules ) == int( ruleNum ):
+ self.newNodeRule( actionPath, ruleNum )
+ return
+ ruleCount = 0
+ for rule in rules:
+ if ruleCount == int( ruleNum ):
+ value = rule.find( "value" )
+ if value is None:
+ value = ""
+ else:
+ value = value.text
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value ] )
+ actionPath = urllib.quote( actionPath )
+ # Rule to change match
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 0 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editMatch&actionPath=" % ltype + actionPath + "&default=" + translated[ 0 ][ 1 ] + "&rule=" + str( ruleCount ) + "&content=NONE"
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 1 ][ 0 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editOperator&actionPath=" % ltype + actionPath + "&group=" + translated[ 1 ][ 1 ] + "&default=" + translated[ 1 ][ 2 ] + "&rule=" + str( ruleCount )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ if not ( translated[ 2 ][ 0 ] ) == "|NONE|":
+ listitem = xbmcgui.ListItem( label="%s" % ( translated[ 2 ][ 1 ] ) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=editValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount )
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ # Check if this match type can be browsed
+ if self.canBrowse( translated[ 0 ][ 1 ] ):
+ #listitem.addContextMenuItems( [(LANGUAGE(30107), "XBMC.RunPlugin(plugin://plugin.library.node.editor?ltype=%s&type=browseValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount ) + "&match=" + translated[ 0 ][ 1 ] + "&content=" + content + ")" )], replaceItems = True )
+ listitem = xbmcgui.ListItem( label=LANGUAGE(30107) )
+ action = "plugin://plugin.library.node.editor?ltype=%s&type=browseValue&actionPath=" % ltype + actionPath + "&rule=" + str( ruleCount ) + "&match=" + translated[ 0 ][ 1 ] + "&content=NONE"
+ xbmcplugin.addDirectoryItem( int(sys.argv[ 1 ]), action, listitem, isFolder=False )
+ #self.browse( translated[ 0 ][ 1 ], content )
+ xbmcplugin.setContent(int(sys.argv[1]), 'files')
+ xbmcplugin.endOfDirectory(handle=int(sys.argv[1]))
+ return
+ ruleCount += 1
+ except:
+ print_exc()
+ self.newNodeRule( actionPath, ruleNum )
+ return
+
+ def newNodeRule( self, actionPath, ruleNum ):
+ # This function creates a new node rule, then re-calls the displayNodeRule function
+ # Split the actionPath, to make things easier
+ ( filePath, fileName ) = os.path.split( actionPath )
+ # Open the rules file if it exists, else create it
+ if ltype == 'video':
+ rulesfile = 'videorules.xml'
+ else:
+ rulesfile = 'musicrules.xml'
+ if os.path.exists( os.path.join( DATAPATH, rulesfile ) ):
+ tree = xmltree.parse( os.path.join( DATAPATH, rulesfile ) )
+ root = tree.getroot()
+ else:
+ tree = xmltree.ElementTree( xmltree.Element( "rules" ) )
+ root = tree.getroot()
+ # See if we already have a element for the node we're parsing
+ nodes = root.findall( "node" )
+ ruleNode = None
+ if nodes is not None:
+ for node in nodes:
+ if node.attrib.get( "name" ) == filePath:
+ ruleNode = node
+ break
+ if ruleNode is None:
+ # We couldn't find an existing element for the node we're parsing - so create one
+ ruleNode = xmltree.SubElement( root, "node" )
+ ruleNode.set( "name", filePath )
+ # Create a new rule
+ ruleTree = self._load_rules().getroot()
+ elems = ruleTree.find( "matches" ).findall( "match" )
+ match = "title"
+ for elem in elems:
+ # We've found the first match for this type
+ match = elem.attrib.get( "name" )
+ operator = elem.find( "operator" ).text
+ break
+ # Find the default operator for this match
+ elems = ruleTree.find( "operators" ).findall( "group" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == operator:
+ operator = elem.find( "operator" ).text
+ break
+ # Write the new rule
+ newRule = xmltree.SubElement( ruleNode, "rule" )
+ newRule.set( "field", match )
+ newRule.set( "operator", operator )
+ xmltree.SubElement( newRule, "value" )
+ # Save the file
+ self.indent( root )
+ tree.write( os.path.join( DATAPATH, rulesfile ), encoding="UTF-8" )
+ # Now add the rule to all views within the node
+ dirs, files = xbmcvfs.listdir( filePath )
+ for file in files:
+ if file == "index.xml":
+ continue
+ elif file.endswith( ".xml" ):
+ filename = os.path.join( filePath, file )
+ try:
+ # Load the xml file
+ tree = xmltree.parse( filename )
+ root = tree.getroot()
+ rule = xmltree.SubElement( root, "rule" )
+ rule.set( "field", match )
+ rule.set( "operator", operator )
+ xmltree.SubElement( rule, "value" )
+ # Save the file
+ self.indent( root )
+ tree.write( filename, encoding="UTF-8" )
+ except:
+ print_exc()
+ # Re-call the displayNodeRule function
+ self.displayNodeRule( actionPath, ruleNum )
+
+ #def editNodeRule( self, actionPath, originalRule, newRule ):
+ def editNodeRule( self, actionPath, ruleNum, match, operator, value ):
+ ( filePath, fileName ) = os.path.split( actionPath )
+ # Update the rule in the rules file
+ if ltype == 'video':
+ rulesfile = 'videorules.xml'
+ else:
+ rulesfile = 'musicrules.xml'
+ try:
+ tree = xmltree.parse( os.path.join( DATAPATH, rulesfile ) )
+ root = tree.getroot()
+ nodes = root.findall( "node" )
+ for node in nodes:
+ if node.attrib.get( "name" ) == filePath:
+ ruleCount = 0
+ rules = node.findall( "rule" )
+ for rule in rules:
+ if ruleCount == int( ruleNum ):
+ # This is the rule we want to update
+ valueElem = rule.find( "value" )
+ if match is None:
+ match = rule.attrib.get( "field" )
+ if operator is None:
+ operator = rule.attrib.get( "operator" )
+ if value is None:
+ if valueElem is None:
+ value = ""
+ else:
+ value = valueElem.text
+ if value is None:
+ value = ""
+ newRule = self.translateRule( [ match, operator, value ] )
+ # Get the original rule
+ origMatch = rule.attrib.get( "field" )
+ origOperator = rule.attrib.get( "operator" )
+ if valueElem is None:
+ origValue = ""
+ else:
+ origValue = valueElem.text
+ originalRule = self.translateRule( [ origMatch, origOperator, origValue ] )
+ # Update the rule
+ rule.set( "field", newRule[ 0 ][ 1 ] )
+ rule.set( "operator", newRule[ 1 ][ 2 ] )
+ if len( newRule ) == 3:
+ if rule.find( "value" ) == None:
+ # Create a new rule node
+ xmltree.SubElement( rule, "value" ).text = newRule[ 2 ][ 0 ]
+ else:
+ rule.find( "value" ).text = newRule[ 2 ][ 0 ]
+ ruleCount += 1
+ # Save the file
+ self.indent( root )
+ tree.write( os.path.join( DATAPATH, rulesfile ), encoding="UTF-8" )
+ except:
+ print_exc()
+ return
+ # Now update the views with the new rule
+ dirs, files = xbmcvfs.listdir( filePath )
+ for file in files:
+ if file == "index.xml":
+ continue
+ elif file.endswith( ".xml" ):
+ filename = os.path.join( filePath, file )
+ # List the rules
+ try:
+ # Load the xml file
+ tree = xmltree.parse( filename )
+ root = tree.getroot()
+ # Look for any rules
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ value = rule.find( "value" )
+ if value is not None and value.text is not None:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text ] )
+ else:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "" ] )
+ if originalRule[ 0 ][ 1 ] == translated[ 0 ][ 1 ] and originalRule[ 1 ][ 2 ] == translated[ 1 ][ 2 ] and originalRule[ 2 ][ 0 ] == translated[ 2 ][ 0 ]:
+ # This is the right rule, update it
+ rule.set( "field", newRule[ 0 ][ 1 ] )
+ rule.set( "operator", newRule[ 1 ][ 2 ] )
+ if value is not None:
+ value.text = newRule[ 2 ][ 0 ]
+ else:
+ xmltree.SubElement( rule, "value" ).text = newRule[ 2 ][ 0 ]
+ break
+ # Save the file
+ self.indent( root )
+ tree.write( filename, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ #def deleteNodeRule( self, actionPath, originalRule ):
+ def deleteNodeRule( self, actionPath, ruleNum ):
+ ( filePath, fileName ) = os.path.split( actionPath )
+ # Delete the rule from the rules file
+ if ltype == 'video':
+ rulesfile = 'videorules.xml'
+ else:
+ rulesfile = 'musicrules.xml'
+ try:
+ tree = xmltree.parse( os.path.join( DATAPATH, rulesfile ) )
+ root = tree.getroot()
+ nodes = root.findall( "node" )
+ for node in nodes:
+ if node.attrib.get( "name" ) == filePath:
+ ruleCount = 0
+ rules = node.findall( "rule" )
+ for rule in rules:
+ if ruleCount == int( ruleNum ):
+ # This is the rule we want to delete
+ # Translate the rule, so we can delete it from the views
+ valueElem = rule.find( "value" )
+ origMatch = rule.attrib.get( "field" )
+ origOperator = rule.attrib.get( "operator" )
+ if valueElem is None:
+ origValue = ""
+ else:
+ origValue = valueElem.text
+ originalRule = self.translateRule( [ origMatch, origOperator, origValue ] )
+ node.remove( rule )
+ ruleCount += 1
+ # Save the file
+ self.indent( root )
+ tree.write( os.path.join( DATAPATH, rulesfile ), encoding="UTF-8" )
+ except:
+ print_exc()
+ return
+ # Now delete the rule from all the views
+ dirs, files = xbmcvfs.listdir( filePath )
+ for file in files:
+ if file == "index.xml":
+ continue
+ elif file.endswith( ".xml" ):
+ filename = os.path.join( filePath, file )
+ # List the rules
+ try:
+ # Load the xml file
+ tree = xmltree.parse( filename )
+ root = tree.getroot()
+ # Look for any rules
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ value = rule.find( "value" )
+ if value is not None and value.text is not None:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text ] )
+ else:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "" ] )
+
+ if originalRule[ 0 ][ 1 ] == translated[ 0 ][ 1 ] and originalRule[ 1 ][ 2 ] == translated[ 1 ][ 2 ] and originalRule[ 2 ][ 0 ] == translated[ 2 ][ 0 ]:
+ # This is the right rule, delete it
+ root.remove( rule )
+ break
+ # Save the file
+ self.indent( root )
+ tree.write( filename, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def deleteAllNodeRules( self, actionPath ):
+ if ltype == 'video':
+ rulesfile = 'videorules.xml'
+ else:
+ rulesfile = 'musicrules.xml'
+ try:
+ # Remove all rules for this parent node from the rules file
+ tree = xmltree.parse( os.path.join( DATAPATH, rulesfile ) )
+ root = tree.getroot()
+ nodes = root.findall( "node" )
+ for node in nodes:
+ if node.attrib.get( "name" ) == actionPath:
+ root.remove( node )
+ # Write the updated file
+ self.indent( root )
+ tree.write( os.path.join( DATAPATH, rulesfile ), encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def isNodeRule( self, viewRule, actionPath ):
+ if actionPath.endswith( "index.xml" ):
+ return False
+ if self.nodeRules is None:
+ self.nodeRules = []
+ # Load all the node rules for current directory
+ ( filePath, fileName ) = os.path.split( actionPath )
+ self.loadNodeRules( filePath )
+ # If there are no node rules, return False
+ if len( self.nodeRules ) == 0:
+ return False
+
+ # Compare the passed in rule with those in self.nodeRules
+ count = 0
+ for nodeRule in self.nodeRules:
+ if nodeRule[0] == viewRule[0][1] and nodeRule[1] == viewRule[1][2] and nodeRule[2] == viewRule[2][0]:
+ # Rule matches
+ self.nodeRules.pop( count )
+ return True
+ count += 1
+ return False
+
+ def addAllNodeRules( self, actionPath, root ):
+ if self.nodeRules is None:
+ self.loadNodeRules( actionPath )
+ if len( self.nodeRules ) == 0:
+ return
+ for nodeRule in self.nodeRules:
+ rule = xmltree.SubElement( root, "rule" )
+ rule.set( "field", nodeRule[ 0 ] )
+ rule.set( "operator", nodeRule[ 1 ] )
+ xmltree.SubElement( rule, "value" ).text = nodeRule[ 2 ]
+
+ def getNodeRules( self, actionPath ):
+ ( filePath, fileName ) = os.path.split( actionPath )
+ if self.nodeRules is None:
+ self.loadNodeRules( filePath )
+ if len( self.nodeRules ) == 0:
+ return None
+ else:
+ return self.nodeRules
+
+ def loadNodeRules( self, actionPath ):
+ self.nodeRules = []
+ # Load all the node rules for current directory
+ #actionPath = os.path.join( actionPath, "index.xml" )
+ if ltype == 'video':
+ filename = os.path.join( DATAPATH, "videorules.xml" )
+ else:
+ filename = os.path.join( DATAPATH, "musicrules.xml" )
+ if os.path.exists( filename ):
+ try:
+ # Load the xml file
+ tree = xmltree.parse( filename )
+ root = tree.getroot()
+ # Find the node element for this path
+ nodes = root.findall( "node" )
+ if nodes is None:
+ return
+ ruleNode = None
+ for node in nodes:
+ if node.attrib.get( "name" ) == actionPath:
+ ruleNode = node
+ break
+ if ruleNode is None:
+ # There don't appear to be any rules
+ return
+ # Look for any rules
+ rules = ruleNode.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ value = rule.find( "value" )
+ if value is not None and value.text is not None:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), value.text ] )
+ else:
+ translated = self.translateRule( [ rule.attrib.get( "field" ), rule.attrib.get( "operator" ), "" ] )
+ # Save the rule
+ self.nodeRules.append( [ translated[0][1], translated[1][2], translated[2][0] ] )
+ except:
+ print_exc()
+
+ def moveNodeRuleToAppdata( self, path, actionPath ):
+ #BETA2 ONLY CODE
+ # This function will move any parent node rules out of the index.xml, and into the rules file in the plugins appdata folder
+ # Open the rules file if it exists, else create it
+ if ltype == 'video':
+ rulesfile = 'videorules.xml'
+ else:
+ rulesfile = 'musicrules.xml'
+ if os.path.exists( os.path.join( DATAPATH, rulesfile ) ):
+ ruleTree = xmltree.parse( os.path.join( DATAPATH, rulesfile ) )
+ ruleRoot = ruleTree.getroot()
+ else:
+ ruleTree = xmltree.ElementTree( xmltree.Element( "rules" ) )
+ ruleRoot = ruleTree.getroot()
+ # See if we already have a element for the node we're parsing
+ nodes = ruleRoot.findall( "node" )
+ ruleNode = None
+ if nodes is not None:
+ for node in nodes:
+ if node.attrib.get( "name" ) == path:
+ ruleNode = node
+ break
+ if ruleNode is None:
+ # We couldn't find an existing element for the node we're parsing - so create one
+ ruleNode = xmltree.SubElement( ruleRoot, "node" )
+ ruleNode.set( "name", path )
+ try:
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ rules = root.findall( "rule" )
+ if rules is not None:
+ for rule in rules:
+ # Create a new rule in the ruleTree
+ newRule = xmltree.SubElement( ruleNode, "rule" )
+ newRule.set( "field", rule.attrib.get( "field" ) )
+ newRule.set( "operator", rule.attrib.get( "operator" ) )
+ value = rule.find( "value" )
+ if value is not None:
+ xmltree.SubElement( newRule, "value" ).text = value.text
+ # Delete the rule from the tree
+ root.remove( rule )
+ # Write both files
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ self.indent( ruleRoot )
+ ruleTree.write( os.path.join( DATAPATH, rulesfile ), encoding="UTF-8" )
+ except:
+ print_exc()
+ #/BETA2 ONLY CODE
+
+ # Functions for browsing for value
+ def canBrowse( self, match, content = None ):
+ # Check whether the match type allows browsing
+ if content == "NONE":
+ content = None
+ # Load the rules
+ tree = self._load_rules()
+ elems = tree.getroot().find( "matches" ).findall( "match" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == match:
+ canBrowse = elem.find( "browse" )
+ if canBrowse is None:
+ # This match type is marked as non-browsable
+ return False
+ if content is None:
+ # If we haven't been passed a content type, allow to browse all
+ return True
+ canBrowse = elem.find( content )
+ if canBrowse is None:
+ # We can't browse for this content type
+ return False
+ # We can browse this content type
+ return True
+ return False
+
+ def browse( self, actionPath, ruleNum, match, content = None ):
+ # This function launches the browser for the given match and content type
+ if content is None or content == "" or content == "NONE":
+ if match != "path" and match != "playlist":
+ # No content parameter passed, so check what contents are valid for
+ # this type
+ tree = self._load_rules()
+ elems = tree.getroot().find( "matches" ).findall( "match" )
+ matches = {}
+ for elem in elems:
+ if elem.attrib.get( "name" ) == match:
+ if ltype == 'video':
+ matches["movies"] = elem.find( "movies" )
+ matches["tvshows"] = elem.find( "tvshows" )
+ matches["episodes"] = elem.find( "episodes" )
+ matches["musicvideos"] = elem.find( "musicvideos" )
+ else:
+ matches["artists"] = elem.find( "artists" )
+ matches["albums"] = elem.find( "albums" )
+ matches["songs"] = elem.find( "songs" )
+ break
+ matchesList = []
+ matchesValue = []
+ # Generate a list of the available content types
+ elems = tree.getroot().find( "content" ).findall( "type" )
+ for elem in elems:
+ if matches[ elem.text ] is not None:
+ matchesList.append( xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) ) )
+ matchesValue.append( elem.text )
+ if len( matchesList ) == 0:
+ return
+ if len( matchesList ) == 1:
+ # Only one returned, no point offering a choice of content type
+ content = matchesValue[ 0 ]
+ else:
+ # Display a select dialog so user can choose their content
+ selectedContent = xbmcgui.Dialog().select( LANGUAGE( 30308 ), matchesList )
+ # If the user selected nothing...
+ if selectedContent == -1:
+ return
+ content = matchesValue[ selectedContent ]
+ if match == "title":
+ self.createBrowseNode( content, None )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "tvshow":
+ if content == "episodes":
+ content = "tvshows"
+ self.createBrowseNode( content, None )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "genre":
+ self.createBrowseNode( content, "genres" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "album":
+ self.createBrowseNode( content, "none" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "country":
+ self.createBrowseNode( content, "countries" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "year":
+ if content == "episodes":
+ content = "tvshows"
+ self.createBrowseNode( content, "years" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "artist":
+ self.createBrowseNode( content, "artists" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "director":
+ self.createBrowseNode( content, "directors" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "actor":
+ if content == "episodes":
+ content = "tvshows"
+ self.createBrowseNode( content, "actors" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "studio":
+ self.createBrowseNode( content, "studios" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "path":
+ returnVal = xbmcgui.Dialog().browse(0, self.niceMatchName( match ), ltype )
+ elif match == "set":
+ self.createBrowseNode( content, "sets" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "tag":
+ self.createBrowseNode( content, "tags" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ elif match == "playlist":
+ returnVal = self.browserPlaylist( self.niceMatchName( match ) )
+ elif match == "virtualfolder":
+ returnVal = self.browserPlaylist( self.niceMatchName( match ) )
+ elif match == "albumartist":
+ self.createBrowseNode( content, "artists" )
+ returnVal = self.browser( self.niceMatchName( match ) )
+ try:
+ # Delete any fake node
+ xbmcvfs.delete( os.path.join( xbmc.translatePath( "special://profile".decode('utf-8') ), "library", ltype, "plugin.library.node.editor", "temp.xml" ) )
+ except:
+ print_exc()
+ if returnVal is not None:
+ returnVal = returnVal.decode( "utf-8" )
+ self.writeUpdatedRule( actionPath, ruleNum, value = returnVal )
+
+ def niceMatchName( self, match ):
+ # This function retrieves the translated label for a given match
+ tree = self._load_rules()
+ elems = tree.getroot().find( "matches" ).findall( "match" )
+ matches = {}
+ for elem in elems:
+ if elem.attrib.get( "name" ) == match:
+ return xbmc.getLocalizedString( int( elem.find( "label" ).text ) )
+
+ def createBrowseNode( self, content, grouping = None ):
+ # This function creates a fake node which we'll use for browsing
+ targetDir = os.path.join( xbmc.translatePath( "special://profile".decode('utf-8') ), "library", ltype, "plugin.library.node.editor" )
+ if not os.path.exists( targetDir ):
+ xbmcvfs.mkdirs( targetDir )
+ # Create a new etree
+ tree = xmltree.ElementTree(xmltree.Element( "node" ) )
+ root = tree.getroot()
+ root.set( "type", "filter" )
+ xmltree.SubElement( root, "label" ).text = "Fake node used for browsing"
+ xmltree.SubElement( root, "content" ).text = content
+ if grouping is not None:
+ xmltree.SubElement( root, "group" ).text = grouping
+ else:
+ order = xmltree.SubElement( root, "order" )
+ order.text = "sorttitle"
+ order.set( "direction", "ascending" )
+ self.indent( root )
+ tree.write( os.path.join( targetDir, "temp.xml" ), encoding="UTF-8" )
+
+ def browser( self, title ):
+ # Browser instance used by majority of browses
+ json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Files.GetDirectory", "params": { "properties": ["title", "file", "thumbnail"], "directory": "library://%s/plugin.library.node.editor/temp.xml", "media": "files" } }' % ltype)
+ json_query = unicode(json_query, 'utf-8', errors='ignore')
+ json_response = json.loads(json_query)
+ listings = []
+ values = []
+ # Add all directories returned by the json query
+ if json_response.has_key('result') and json_response['result'].has_key('files') and json_response['result']['files'] is not None:
+ for item in json_response['result']['files']:
+ if item[ "label" ] == "..":
+ continue
+ thumb = None
+ if item[ "thumbnail" ] is not "":
+ thumb = item[ "thumbnail" ]
+ listitem = xbmcgui.ListItem(label=item[ "label" ], iconImage=thumb )
+ listitem.setProperty( "thumbnail", thumb )
+ listings.append( listitem )
+ values.append( item[ "label" ] )
+ # Show dialog
+ w = ShowDialog( "DialogSelect.xml", CWD, listing=listings, windowtitle=title )
+ w.doModal()
+ selectedItem = w.result
+ del w
+ if selectedItem == "" or selectedItem == -1:
+ return None
+ return values[ selectedItem ]
+
+ def browserPlaylist( self, title ):
+ # Browser instance used by playlists
+ json_query = xbmc.executeJSONRPC('{ "jsonrpc": "2.0", "id": 0, "method": "Files.GetDirectory", "params": { "properties": ["title", "file", "thumbnail"], "directory": "special://%splaylists/", "media": "files" } }' % ltype)
+ json_query = unicode(json_query, 'utf-8', errors='ignore')
+ json_response = json.loads(json_query)
+ listings = []
+ values = []
+ # Add all directories returned by the json query
+ if json_response.has_key('result') and json_response['result'].has_key('files') and json_response['result']['files'] is not None:
+ for item in json_response['result']['files']:
+ if item[ "label" ] == "..":
+ continue
+ thumb = None
+ if item[ "thumbnail" ] is not "":
+ thumb = item[ "thumbnail" ]
+ listitem = xbmcgui.ListItem(label=item[ "label" ], iconImage=thumb )
+ listitem.setProperty( "thumbnail", thumb )
+ listings.append( listitem )
+ values.append( item[ "label" ] )
+ # Show dialog
+ w = ShowDialog( "DialogSelect.xml", CWD, listing=listings, windowtitle=title )
+ w.doModal()
+ selectedItem = w.result
+ del w
+ if selectedItem == "" or selectedItem == -1:
+ return None
+ return values[ selectedItem ]
+
+ # in-place prettyprint formatter
+ def indent( self, elem, level=0 ):
+ i = "\n" + level*"\t"
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + "\t"
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ self.indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
+
+# ============================
+# === PRETTY SELECT DIALOG ===
+# ============================
+class ShowDialog( xbmcgui.WindowXMLDialog ):
+ def __init__( self, *args, **kwargs ):
+ xbmcgui.WindowXMLDialog.__init__( self )
+ self.listing = kwargs.get( "listing" )
+ self.windowtitle = kwargs.get( "windowtitle" )
+ self.result = -1
+
+ def onInit(self):
+ try:
+ self.fav_list = self.getControl(6)
+ self.getControl(3).setVisible(False)
+ except:
+ print_exc()
+ self.fav_list = self.getControl(3)
+ self.getControl(5).setVisible(False)
+ self.getControl(1).setLabel(self.windowtitle)
+ for item in self.listing :
+ listitem = xbmcgui.ListItem(label=item.getLabel(), label2=item.getLabel2(), iconImage=item.getProperty( "icon" ), thumbnailImage=item.getProperty( "thumbnail" ))
+ listitem.setProperty( "Addon.Summary", item.getLabel2() )
+ self.fav_list.addItem( listitem )
+ self.setFocus(self.fav_list)
+
+ def onAction(self, action):
+ if action.getId() in ( 9, 10, 92, 216, 247, 257, 275, 61467, 61448, ):
+ self.result = -1
+ self.close()
+
+ def onClick(self, controlID):
+ if controlID == 6 or controlID == 3:
+ num = self.fav_list.getSelectedPosition()
+ self.result = num
+ else:
+ self.result = -1
+ self.close()
+
+ def onFocus(self, controlID):
+ pass
diff --git a/plugin.library.node.editor/resources/lib/viewattrib.py b/plugin.library.node.editor/resources/lib/viewattrib.py
new file mode 100755
index 0000000..398fc03
--- /dev/null
+++ b/plugin.library.node.editor/resources/lib/viewattrib.py
@@ -0,0 +1,367 @@
+# coding=utf-8
+import os, sys
+import xbmc, xbmcaddon, xbmcplugin, xbmcgui, xbmcvfs
+import xml.etree.ElementTree as xmltree
+import urllib
+import json
+from traceback import print_exc
+import pluginBrowser
+
+ADDON = xbmcaddon.Addon()
+ADDONID = ADDON.getAddonInfo('id').decode( 'utf-8' )
+ADDONVERSION = ADDON.getAddonInfo('version')
+LANGUAGE = ADDON.getLocalizedString
+CWD = ADDON.getAddonInfo('path').decode("utf-8")
+ADDONNAME = ADDON.getAddonInfo('name').decode("utf-8")
+DEFAULTPATH = xbmc.translatePath( os.path.join( CWD, 'resources' ).encode("utf-8") ).decode("utf-8")
+ltype = sys.modules[ '__main__' ].ltype
+
+def log(txt):
+ if isinstance (txt,str):
+ txt = txt.decode('utf-8')
+ message = u'%s: %s' % (ADDONID, txt)
+ xbmc.log(msg=message.encode('utf-8'), level=xbmc.LOGDEBUG)
+
+class ViewAttribFunctions():
+ def __init__(self):
+ pass
+
+ def _load_rules( self ):
+ if ltype == 'video':
+ overridepath = os.path.join( DEFAULTPATH , "videorules.xml" )
+ else:
+ overridepath = os.path.join( DEFAULTPATH , "musicrules.xml" )
+ try:
+ tree = xmltree.parse( overridepath )
+ return tree
+ except:
+ return None
+
+ def translateContent( self, content ):
+ # Load the rules
+ tree = self._load_rules()
+ hasValue = True
+ elems = tree.getroot().find( "content" ).findall( "type" )
+ for elem in elems:
+ if elem.text == content:
+ return xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) )
+ return None
+
+ def editContent( self, actionPath, default ):
+ # Load all the rules
+ tree = self._load_rules().getroot()
+ elems = tree.find( "content" ).findall( "type" )
+ selectName = []
+ selectValue = []
+ # Find all the content types
+ for elem in elems:
+ selectName.append( xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) ) )
+ selectValue.append( elem.text )
+ # Let the user select a content type
+ selectedContent = xbmcgui.Dialog().select( LANGUAGE( 30309 ), selectName )
+ # If the user selected no operator...
+ if selectedContent == -1:
+ return
+ self.writeUpdatedRule( actionPath, "content", selectValue[ selectedContent ], addFilter = True )
+
+ def translateGroup( self, grouping ):
+ # Load the rules
+ tree = self._load_rules()
+ hasValue = True
+ elems = tree.getroot().find( "groupings" ).findall( "grouping" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == grouping:
+ return xbmc.getLocalizedString( int( elem.find( "label" ).text ) )
+ return None
+
+ def editGroup( self, actionPath, content, default ):
+ # Load all the rules
+ tree = self._load_rules().getroot()
+ elems = tree.find( "groupings" ).findall( "grouping" )
+ selectName = []
+ selectValue = []
+ # Find all the content types
+ for elem in elems:
+ checkContent = elem.find( content )
+ if checkContent is not None:
+ selectName.append( xbmc.getLocalizedString( int( elem.find( "label" ).text ) ) )
+ selectValue.append( elem.attrib.get( "name" ) )
+ # Let the user select a content type
+ selectedGrouping = xbmcgui.Dialog().select( LANGUAGE( 30310 ), selectName )
+ # If the user selected no operator...
+ if selectedGrouping == -1:
+ return
+ self.writeUpdatedRule( actionPath, "group", selectValue[ selectedGrouping ] )
+
+ def addLimit( self, actionPath ):
+ # Load all the rules
+ try:
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Add a new content tag
+ newContent = xmltree.SubElement( root, "limit" )
+ newContent.text = "25"
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def editLimit( self, actionPath, curValue ):
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30311 ), curValue, type=xbmcgui.INPUT_NUMERIC )
+ if returnVal != "":
+ self.writeUpdatedRule( actionPath, "limit", returnVal )
+
+ def addPath( self, actionPath ):
+ # Load all the rules
+ tree = self._load_rules().getroot()
+ elems = tree.find( "paths" ).findall( "type" )
+ selectName = []
+ selectValue = []
+ # Find all the path types
+ for elem in elems:
+ selectName.append( xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) ) )
+ selectValue.append( elem.attrib.get( "name" ) )
+ # Find any sub-path types
+ for subElem in elem.findall( "type" ):
+ selectName.append( " - %s" %( xbmc.getLocalizedString( int( subElem.attrib.get( "label" ) ) ) ) )
+ selectValue.append( "%s/%s" %( elem.attrib.get( "name" ), subElem.attrib.get( "name" ) ) )
+
+ # Add option to select a plugin
+ selectName.append( LANGUAGE( 30514 ) )
+ selectValue.append( "::PLUGIN::" )
+
+ # Let the user select a path
+ selectedContent = xbmcgui.Dialog().select( LANGUAGE( 30309 ), selectName )
+ # If the user selected no operator...
+ if selectedContent == -1:
+ return
+ if selectValue[ selectedContent ] == "::PLUGIN::":
+ # The user has asked to browse for a plugin
+ path = pluginBrowser.getPluginPath()
+ if path is not None:
+ # User has selected a plugin
+ self.writeUpdatedPath( actionPath, (0, path), addFolder = True)
+ else:
+ # The user has chosen a specific path
+ self.writeUpdatedPath( actionPath, (0, selectValue[ selectedContent ] ), addFolder = True )
+
+ def editPath( self, actionPath, curValue ):
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30312 ), curValue, type=xbmcgui.INPUT_ALPHANUM )
+ if returnVal != "":
+ self.writeUpdatedRule( actionPath, "path", returnVal.decode( "utf-8" ) )
+
+ def editIcon( self, actionPath, curValue ):
+ returnVal = xbmcgui.Dialog().input( LANGUAGE( 30313 ), curValue, type=xbmcgui.INPUT_ALPHANUM )
+ if returnVal != "":
+ self.writeUpdatedRule( actionPath, "icon", returnVal.decode( "utf-8" ) )
+
+ def browseIcon( self, actionPath ):
+ returnVal = xbmcgui.Dialog().browse( 2, LANGUAGE( 30313 ), "files", useThumbs = True )
+ if returnVal:
+ self.writeUpdatedRule( actionPath, "icon", returnVal )
+
+ def writeUpdatedRule( self, actionPath, attrib, value, addFilter = False ):
+ # This function writes an updated match, operator or value to a rule
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Add type="filter" if requested
+ if addFilter:
+ root.set( "type", "filter" )
+ # Find the attribute and update it
+ elem = root.find( attrib )
+ if elem is None:
+ # There's no existing attribute with this name, so create one
+ elem = xmltree.SubElement( root, attrib )
+ elem.text = value
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def writeUpdatedPath( self, actionPath, newComponent, addFolder = False ):
+ # This functions writes an updated path
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Add type="folder" if requested
+ if addFolder:
+ root.set( "type", "folder" )
+ # Find the current path element
+ elem = root.find( "path" )
+ if elem is None:
+ # There's no existing path element, so create one
+ elem = xmltree.SubElement( root, "path" )
+ # Get the split version of the path
+ splitPath = self.splitPath( elem.text )
+ elem.text = ""
+ if len( splitPath ) == 0:
+ # If the splitPath is empty, add our new component straight away
+ elem.text = "%s/" %( newComponent[ 1 ] )
+ elif newComponent[ 0 ] == 0 and newComponent[ 1 ].startswith( "plugin://"):
+ # We've been passed a plugin, so only want to write that plugin
+ elem.text = newComponent[ 1 ]
+ else:
+ # Enumarate through everything in the existing path
+ for x, component in enumerate( splitPath ):
+ if x != newComponent[ 0 ]:
+ # Transfer this component to the new path
+ if x == 0:
+ elem.text = self.joinPath( component )
+ elif x == 1:
+ elem.text += "?%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ else:
+ elem.text += "&%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ else:
+ # Add our new component
+ if x == 0:
+ elem.text = "%s/" %( newComponent[ 1 ] )
+ elif x == 1:
+ elem.text += "?%s=%s" %( newComponent[ 1 ], urllib.quote( newComponent[ 2 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ else:
+ elem.text += "&%s=%s" %( newComponent[ 1 ], urllib.quote( newComponent[ 2 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ # Check that we added it
+ if x < newComponent[ 0 ]:
+ if newComponent[ 0 ] == 1:
+ elem.text += "?%s=%s" %( newComponent[ 1 ], urllib.quote( newComponent[ 2 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ else:
+ elem.text += "&%s=%s" %( newComponent[ 1 ], urllib.quote( newComponent[ 2 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def deletePathRule( self, actionPath, rule ):
+ # This function deletes a rule from a path component
+ result = xbmcgui.Dialog().yesno(ADDONNAME, LANGUAGE( 30407 ) )
+ if not result:
+ return
+
+ try:
+ # Load the xml file
+ tree = xmltree.parse( actionPath )
+ root = tree.getroot()
+ # Find the current path element
+ elem = root.find( "path" )
+ # Get the split version of the path
+ splitPath = self.splitPath( elem.text )
+ elem.text = ""
+
+ # Enumarate through everything in the existing path
+ addedQ = False
+ for x, component in enumerate( splitPath ):
+ if x != rule:
+ # Transfer this component to the new path
+ if x == 0:
+ elem.text = self.joinPath( component )
+ elif not addedQ:
+ elem.text += "?%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ addedQ = True
+ else:
+ elem.text += "&%s=%s" %( component[ 0 ], urllib.quote( component[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) )
+ # Save the file
+ self.indent( root )
+ tree.write( actionPath, encoding="UTF-8" )
+ except:
+ print_exc()
+
+ def splitPath( self, completePath ):
+ # This function returns an array of the different components of a path
+ # [library]://[primary path]/[secondary path]/?attribute1=value1&attribute2=value2...
+ # [( , )] [( , )] [( , )]...
+ splitPath = []
+
+ # If completePath is empty, return an empty list
+ if completePath is None:
+ return []
+
+ # If it's a plugin, then we don't want to split it as its unlikely the user will want to edit individual components
+ if completePath.startswith( "plugin://" ):
+ return [ ( completePath, None ) ]
+
+ # Split, get the library://primarypath/[secondarypath]
+ split = completePath.rsplit( "/", 1 )
+ if split[ 0 ].count( "/" ) == 3:
+ # There's a secondary path
+ paths = split[ 0 ].rsplit( "/", 1 )
+ splitPath.append( ( paths[0], paths[1] ) )
+ else:
+ splitPath.append( ( split[ 0 ], None ) )
+
+
+ # Now split the components
+ if len( split ) != 1 and split[ 1 ].startswith( "?" ):
+ for component in split[ 1 ][ 1: ].split( "&" ):
+ componentSplit = component.split( "=" )
+ splitPath.append( ( componentSplit[ 0 ], urllib.unquote( componentSplit[ 1 ].encode( "utf-8" ) ).decode( "utf-8" ) ) )
+
+ return splitPath
+
+ def joinPath( self, components ):
+ # This function rejoins the library://path/subpath components of a path
+ returnPath = "%s/" %( components[ 0 ] )
+ if components[ 1 ] is not None:
+ returnPath += "%s/" %( components[ 1 ] )
+ return returnPath
+
+
+ def translatePath( self, path ):
+ # Load the rules
+ tree = self._load_rules()
+ subSearch = None
+ translated = [ path[ 0 ], path[ 1 ] ]
+ elems = tree.getroot().find( "paths" ).findall( "type" )
+ for elem in elems:
+ if elem.attrib.get( "name" ) == path[ 0 ]:
+ translated[ 0 ] = xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) )
+ subSearch = elem
+ break
+
+ if path[ 1 ] and subSearch is not None:
+ for elem in subSearch.findall( "type" ):
+ if elem.attrib.get( "name" ) == path[ 1 ]:
+ translated[ 1 ] = xbmc.getLocalizedString( int( elem.attrib.get( "label" ) ) )
+ break
+
+ returnString = translated[ 0 ]
+ if translated[ 1 ]:
+ returnString += " - %s" %( translated[ 1 ] )
+
+ return returnString
+
+ def translateMatch( self, value ):
+ if value == "any":
+ return xbmc.getLocalizedString(21426).capitalize()
+ else:
+ return xbmc.getLocalizedString(21425).capitalize()
+
+ def editMatch( self, actionPath ):
+ selectName = [ xbmc.getLocalizedString(21425).capitalize(), xbmc.getLocalizedString(21426).capitalize() ]
+ selectValue = [ "all", "any" ]
+ # Let the user select wether any or all rules need match
+ selectedMatch = xbmcgui.Dialog().select( LANGUAGE( 30310 ), selectName )
+ # If the user made no selection...
+ if selectedMatch == -1:
+ return
+ self.writeUpdatedRule( actionPath, "match", selectValue[ selectedMatch ] )
+
+ # in-place prettyprint formatter
+ def indent( self, elem, level=0 ):
+ i = "\n" + level*"\t"
+ if len(elem):
+ if not elem.text or not elem.text.strip():
+ elem.text = i + "\t"
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ for elem in elem:
+ self.indent(elem, level+1)
+ if not elem.tail or not elem.tail.strip():
+ elem.tail = i
+ else:
+ if level and (not elem.tail or not elem.tail.strip()):
+ elem.tail = i
diff --git a/plugin.library.node.editor/resources/musicrules.xml b/plugin.library.node.editor/resources/musicrules.xml
new file mode 100644
index 0000000..92ed4ec
--- /dev/null
+++ b/plugin.library.node.editor/resources/musicrules.xml
@@ -0,0 +1,323 @@
+<rules>
+ <matches>
+ <match name="artist">
+ <label>557</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="genre">
+ <label>515</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="moods">
+ <label>175</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>string</operator>
+ </match>
+ <match name="styles">
+ <label>176</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <operator>string</operator>
+ </match>
+ <match name="instruments">
+ <label>21892</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="biography">
+ <label>21887</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="born">
+ <label>21893</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="formed">
+ <label>21894</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="disbanded">
+ <label>21896</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="died">
+ <label>21897</label>
+ <artists>True</artists>
+ <operator>string</operator>
+ </match>
+ <match name="playlist">
+ <label>559</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>isornot</operator>
+ <browse>True</browse>
+ </match>
+ <match name="virtualfolder">
+ <label>614</label>
+ <artists>True</artists>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>isornot</operator>
+ <browse>True</browse>
+ </match>
+ <match name="album">
+ <label>558</label>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="albumartist">
+ <label>566</label>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="year">
+ <label>345</label>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>numeric</operator>
+ <browse>True</browse>
+ </match>
+ <match name="review">
+ <label>183</label>
+ <albums>True</albums>
+ <operator>string</operator>
+ </match>
+ <match name="themes">
+ <label>21895</label>
+ <albums>True</albums>
+ <operator>string</operator>
+ </match>
+ <match name="type">
+ <label>564</label>
+ <albums>True</albums>
+ <operator>string</operator>
+ </match>
+ <match name="label">
+ <label>21899</label>
+ <albums>True</albums>
+ <operator>string</operator>
+ </match>
+ <match name="rating">
+ <label>563</label>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>numeric</operator>
+ </match>
+ <match name="playcount">
+ <label>567</label>
+ <albums>True</albums>
+ <songs>True</songs>
+ <operator>numeric</operator>
+ </match>
+ <match name="title">
+ <label>556</label>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="duration">
+ <label>180</label>
+ <songs>True</songs>
+ <operator>time</operator>
+ </match>
+ <match name="track">
+ <label>554</label>
+ <songs>True</songs>
+ <operator>numeric</operator>
+ </match>
+ <match name="file">
+ <label>561</label>
+ <songs>True</songs>
+ <operator>string</operator>
+ </match>
+ <match name="path">
+ <label>573</label>
+ <songs>True</songs>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="lastplayed">
+ <label>568</label>
+ <songs>True</songs>
+ <operator>date</operator>
+ </match>
+ <match name="comment">
+ <label>569</label>
+ <songs>True</songs>
+ <operator>string</operator>
+ </match>
+ </matches>
+ <operators>
+ <group name="string">
+ <operator label="21400">contains</operator>
+ <operator label="21401">doesnotcontain</operator>
+ <operator label="21404">startswith</operator>
+ <operator label="21405">endswith</operator>
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ </group>
+ <group name="numeric">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ <operator label="21406">greaterthan</operator>
+ <operator label="21407">lessthan</operator>
+ </group>
+ <group name="time">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ <operator label="21406">greaterthan</operator>
+ <operator label="21407">lessthan</operator>
+ </group>
+ <group name="date">
+ <operator label="21408">after</operator>
+ <operator label="21409">before</operator>
+ <operator label="21410" type="integer">inthelast</operator>
+ <operator label="21411" type="integer">notinthelast</operator>
+ </group>
+ <group name="isornot">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ </group>
+ </operators>
+ <groupings>
+ <grouping name="none">
+ <label>16018</label>
+ <artists>True</artists>
+ </grouping>
+ <grouping name="genres">
+ <label>135</label>
+ <artists>True</artists>
+ </grouping>
+ <grouping name="years">
+ <label>652</label>
+ <albums>True</albums>
+ </grouping>
+ </groupings>
+ <orderby>
+ <type label="21430">ascending</type>
+ <type label="21431">descending</type>
+ </orderby>
+ <content>
+ <type label="133">artists</type>
+ <type label="132">albums</type>
+ <type label="134">songs</type>
+ </content>
+
+ <paths>
+ <type label="135" name="musicdb://genres"/>
+ <type label="133" name="musicdb://artists"/>
+ <type label="132" name="musicdb://albums"/>
+ <type label="1050" name="musicdb://singles"/>
+ <type label="134" name="musicdb://songs"/>
+ <type label="271" name="musicdb://top100">
+ <type label="134" name="songs"/>
+ <type label="132" name="albums"/>
+ </type>
+ <type label="359" name="musicdb://recentlyaddedalbums"/>
+ <type label="517" name="musicdb://recentlyplayedalbums"/>
+ <type label="521" name="musicdb://compilations"/>
+ <type label="652" name="musicdb://years"/>
+ <type label="744" name="sources://music">
+ <content>None</content>
+ </type>
+ <type label="136" name="special://videoplaylists">
+ <content>None</content>
+ </type>
+ </paths>
+
+ <pathRules>
+ <rule name="roleid" label="30510">
+ <value>integer</value>
+ <content>artists</content>
+ <content>albums</content>
+ </rule>
+ <rule name="role" label="38033">
+ <value>string</value>
+ <content>artists</content>
+ <content>albums</content>
+ </rule>
+ <rule name="artistid" label="30508">
+ <value>integer</value>
+ <content>artists</content>
+ <content>albums</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://artists/</browse>
+ </rule>
+ <rule name="genreid" label="30500">
+ <value>integer</value>
+ <content>artists</content>
+ <content>albums</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://genres/</browse>
+ </rule>
+ <rule name="genre" label="515">
+ <value>string</value>
+ <content>artists</content>
+ <content>albums</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://genres/</browse>
+ </rule>
+ <rule name="albumid" label="30509">
+ <value>integer</value>
+ <content>artists</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://albums/</browse>
+ </rule>
+ <rule name="album" label="558">
+ <value>string</value>
+ <content>artists</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://albums/</browse>
+ </rule>
+ <rule name="songid" label="30511">
+ <value>integer</value>
+ <content>artists</content>
+ <browse>musicdb://songs/</browse>
+ </rule>
+ <rule name="albumartistsonly" label="30512">
+ <value>boolean</value>
+ <content>artists</content>
+ </rule>
+ <rule name="year" label="345">
+ <value>integer</value>
+ <content>albums</content>
+ <content>songs</content>
+ <content>singles</content>
+ <browse>musicdb://years/</browse>
+ </rule>
+ <rule name="compilation" label="521">
+ <value>boolean</value>
+ <content>albums</content>
+ <content>songs</content>
+ <content>singles</content>
+ </rule>
+ <rule name="showsingles" label="30513">
+ <value>boolean</value>
+ <content>albums</content>
+ </rule>
+ </pathRules>
+</rules>
diff --git a/plugin.library.node.editor/resources/videorules.xml b/plugin.library.node.editor/resources/videorules.xml
new file mode 100755
index 0000000..21926f7
--- /dev/null
+++ b/plugin.library.node.editor/resources/videorules.xml
@@ -0,0 +1,529 @@
+<rules>
+ <matches>
+ <match name="title">
+ <label>556</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="tvshow">
+ <label>20364</label>
+ <episodes>True</episodes>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="plot">
+ <label>207</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ </match>
+ <match name="status">
+ <label>126</label>
+ <tvshows>True</tvshows>
+ <operator>string</operator>
+ </match>
+ <match name="votes">
+ <movies>True</movies>
+ <label>205</label>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <operator>string</operator>
+ </match>
+ <match name="plotoutline">
+ <label>203</label>
+ <movies>True</movies>
+ <operator>string</operator>
+ </match>
+ <match name="tagline">
+ <label>202</label>
+ <movies>True</movies>
+ <operator>string</operator>
+ </match>
+ <match name="rating">
+ <label>563</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <operator>numeric</operator>
+ </match>
+ <match name="time">
+ <label>180</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>time</operator>
+ </match>
+ <match name="writers">
+ <label>20417</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <operator>string</operator>
+ </match>
+ <match name="airdate">
+ <label>20416</label>
+ <episodes>True</episodes>
+ <operator>date</operator>
+ </match>
+ <match name="playcount">
+ <label>567</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>numeric</operator>
+ </match>
+ <match name="lastplayed">
+ <label>568</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>date</operator>
+ </match>
+ <match name="inprogress">
+ <label>575</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <operator>boolean</operator>
+ </match>
+ <match name="genre">
+ <label>515</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="album">
+ <label>558</label>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="country">
+ <label>574</label>
+ <movies>True</movies>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="year">
+ <label>562</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>numeric</operator>
+ <browse>True</browse>
+ </match>
+ <match name="artist">
+ <label>557</label>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="director">
+ <label>20339</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="actor">
+ <label>20337</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="episode">
+ <label>20359</label>
+ <episodes>True</episodes>
+ <operator>numeric</operator>
+ </match>
+ <match name="season">
+ <label>20373</label>
+ <episodes>True</episodes>
+ <operator>numeric</operator>
+ </match>
+ <match name="numepisodes">
+ <label>20360</label>
+ <tvshows>True</tvshows>
+ <operator>numeric</operator>
+ </match>
+ <match name="numwatched">
+ <label>21457</label>
+ <tvshows>True</tvshows>
+ <operator>numeric</operator>
+ </match>
+ <match name="mpaarating">
+ <label>20074</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <operator>string</operator>
+ </match>
+ <match name="top250">
+ <label>13409</label>
+ <movies>True</movies>
+ <operator>numeric</operator>
+ </match>
+ <match name="studio">
+ <label>20388</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="hastrailer">
+ <label>20423</label>
+ <movies>True</movies>
+ <operator>boolean</operator>
+ </match>
+ <match name="filename">
+ <label>561</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ </match>
+ <match name="path">
+ <label>573</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="set">
+ <label>20457</label>
+ <movies>True</movies>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="tag">
+ <label>20459</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ <browse>True</browse>
+ </match>
+ <match name="dateadded">
+ <label>570</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>date</operator>
+ </match>
+ <match name="videoresolution">
+ <label>21443</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>numeric</operator>
+ </match>
+ <match name="audiochannels">
+ <label>21444</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>string</operator>
+ </match>
+ <match name="videocodec">
+ <label>21445</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ </match>
+ <match name="audiocodec">
+ <label>21446</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ </match>
+ <match name="audiolanguage">
+ <label>21447</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ </match>
+ <match name="subtitlelanguage">
+ <label>21448</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ </match>
+ <match name="videoaspect">
+ <label>21374</label>
+ <movies>True</movies>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>numeric</operator>
+ </match>
+ <match name="playlist">
+ <label>559</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ <browse>True</browse>
+ </match>
+ <match name="virtualfolder">
+ <label>614</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ <operator>isornot</operator>
+ <browse>True</browse>
+ </match>
+ </matches>
+ <operators>
+ <group name="string">
+ <operator label="21400">contains</operator>
+ <operator label="21401">doesnotcontain</operator>
+ <operator label="21404">startswith</operator>
+ <operator label="21405">endswith</operator>
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ </group>
+ <group name="numeric">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ <operator label="21406">greaterthan</operator>
+ <operator label="21407">lessthan</operator>
+ </group>
+ <group name="time">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ <operator label="21406">greaterthan</operator>
+ <operator label="21407">lessthan</operator>
+ </group>
+ <group name="date">
+ <operator label="21408">after</operator>
+ <operator label="21409">before</operator>
+ <operator label="21410" type="integer">inthelast</operator>
+ <operator label="21411" type="integer">notinthelast</operator>
+ </group>
+ <group name="boolean" option="novalue">
+ <operator label="20122">true</operator>
+ <operator label="20424">false</operator>
+ </group>
+ <group name="isornot">
+ <operator label="21402">is</operator>
+ <operator label="21403">isnot</operator>
+ </group>
+ </operators>
+ <groupings>
+ <grouping name="none">
+ <label>16018</label>
+ <movies>True</movies>
+ </grouping>
+ <grouping name="genres">
+ <label>135</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ <grouping name="years">
+ <label>652</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ <grouping name="actors">
+ <label>344</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ </grouping>
+ <grouping name="artists">
+ <label>133</label>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ <grouping name="directors">
+ <label>20348</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <episodes>True</episodes>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ <grouping name="studios">
+ <label>20388</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ <grouping name="countries">
+ <label>20451</label>
+ <movies>True</movies>
+ </grouping>
+ <grouping name="sets">
+ <label>20434</label>
+ <movies>True</movies>
+ </grouping>
+ <grouping name="tags">
+ <label>20459</label>
+ <movies>True</movies>
+ <tvshows>True</tvshows>
+ <musicvideos>True</musicvideos>
+ </grouping>
+ </groupings>
+ <orderby>
+ <type label="21430">ascending</type>
+ <type label="21431">descending</type>
+ </orderby>
+ <content>
+ <type label="342">movies</type>
+ <type label="20343">tvshows</type>
+ <type label="20360">episodes</type>
+ <type label="20389">musicvideos</type>
+ </content>
+
+ <paths>
+ <type label="342" name="videodb://movies">
+ <content>movies</content>
+ <type label="135" name="genres"/>
+ <type label="369" name="titles"/>
+ <type label="652" name="years"/>
+ <type label="344" name="actors"/>
+ <type label="20348" name="directors"/>
+ <type label="20388" name="studios"/>
+ <type label="20434" name="sets"/>
+ <type label="20451" name="countries"/>
+ <type label="20459" name="tags"/>
+ </type>
+ <type label="20343" name="videodb://tvshows">
+ <content>tvshows</content>
+ <type label="135" name="genres"/>
+ <type label="369" name="titles"/>
+ <type label="652" name="years"/>
+ <type label="344" name="actors"/>
+ <type label="20388" name="studios"/>
+ <type label="20459" name="tags"/>
+ </type>
+ <type label="20389" name="videodb://musicvideos">
+ <content>musicvideos</content>
+ <type label="135" name="genres"/>
+ <type label="369" name="titles"/>
+ <type label="652" name="years"/>
+ <type label="133" name="artists"/>
+ <type label="132" name="albums"/>
+ <type label="20348" name="directors"/>
+ <type label="20388" name="studios"/>
+ <type label="20459" name="tags"/>
+ </type>
+ <type label="20386" name="videodb://recentlyaddedmovies">
+ <content>movies</content>
+ </type>
+ <type label="20387" name="videodb://recentlyaddedepisodes">
+ <content>tvshows</content>
+ </type>
+ <type label="20390" name="videodb://recentlyaddedmusicvideos">
+ <content>musicvideos</content>
+ </type>
+ <type label="626" name="videodb://inprogresstvshows">
+ <content>tvshows</content>
+ </type>
+ <type label="744" name="sources://video">
+ <content>None</content>
+ </type>
+ <type label="136" name="special://videoplaylists">
+ <content>None</content>
+ </type>
+ <type label="1037" name="addons://sources/video">
+ <content>None</content>
+ </type>
+ </paths>
+ <pathRules>
+ <rule label="30500" name="genreid">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <content>musicvideos</content>
+ <browse>videodb://::root::/genres/</browse>
+ </rule>
+ <rule label="30501" name="countryid">
+ <value>integer</value>
+ <content>movies</content>
+ <browse>videodb://movies/countries/</browse>
+ </rule>
+ <rule label="30502" name="studioid">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <content>musicvideos</content>
+ <browse>videodb://::root::/studios/</browse>
+ </rule>
+ <rule label="30503" name="directorid">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <content>musicvideos</content>
+ <browse>videodb://::root::/directors/</browse>
+ </rule>
+ <rule label="345" name="year">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <content>musicvideos</content>
+ <browse>videodb://::root::/years/</browse>
+ </rule>
+ <rule label="30504" name="actorid">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <browse>videodb://::root::/actors/</browse>
+ </rule>
+ <rule label="30505" name="setid">
+ <value>integer</value>
+ <content>movies</content>
+ <browse>videodb://::root::/sets/</browse>
+ </rule>
+ <rule label="30506" name="tagid">
+ <value>integer</value>
+ <content>movies</content>
+ <content>tvshows</content>
+ <browse>videodb://::root::/tags/</browse>
+ </rule>
+ <rule label="30507" name="tvshowid">
+ <value>integer</value>
+ <content>tvshows</content>
+ <browse>videodb://tvshows/</browse>
+ </rule>
+ <rule label="20373" name="season">
+ <value>integer</value>
+ <content>tvshows</content>
+ </rule>
+ <rule label="30508" name="artistid">
+ <value>integer</value>
+ <content>musicvideos</content>
+ <browse>videodb://musicvideos/artists/</browse>
+ </rule>
+ <rule label="30509" name="albumid">
+ <value>integer</value>
+ <content>musicvideos</content>
+ <browse>videodb://musicvideos/albums/</browse>
+ </rule>
+ </pathRules>
+</rules>