pisg-0.73/0000775000076400007650000000000011705647720011053 5ustar wadewadepisg-0.73/COPYING0000774000076400007650000004310511705647720012113 0ustar wadewade GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 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 Library 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. Copyright (C) 19yy 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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) 19yy 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. , 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 Library General Public License instead of this License. pisg-0.73/lang.txt0000774000076400007650000075053211705647720012553 0ustar wadewade# To use a translation, set 'lang' in the pisg configuration file, e.g.: # # # # to get a page in Danish. # # Translations in this file with current maintainers: # # (EN) English # (DE) German - Christoph Berg (2005-07-28) # (NO) Norwegian - Andreas Blaafladt # (PT) Portuguese - MrWho # (PT_BR) Portuguese/BR(Brazil) - francisco lopes # (DA) Danish - Morten Brix Pedersen # (FR) French - Molator # (ES) Spanish - Sheuron Azxe # last update: 2005-01-14 by Anonymous # (PL) Polish - Gandalf the Grey # (NL_BE) Flemish - Tiniduske (2004-10-15) # (NL) Dutch - Jeroen van Nimwegen (2005-02-17) # (SE) Swedish - Andreas Henriksson (2005-01-12) # (FI) Finnish - Kirler@paincreators # last update: Mikko Nissinen (2005-07-10) # (SI) Slovenian - Ales Tepina (2005-01-09: bounces) # (HU) Hungarian - Gyuri Horak (2005-01-09: bounces) # (EE) Estonian - Hannes Tarien (2005-09-06) # (IT) Italian - Michele Venturi (2005-04-29) # (CA) Catalan - Nikoru Kimochi (2005-01-09: bounces) # (TR) Turkish - cti- (2005-01-09: bounces) # (RO) Romanian - Parcalabior Vald # (IS) Icelandic - Birkir Hreinsson # (CZ) Czech - Jaroslav Ostadal (2005-01-14: bounces) # last update: Pavel Kouril (2006-04-30) # (SK) Slovak - Gabriel Svajko # (RU) Russian - Anton Tretiakov # (GR) Greek - Konstantinos Tzanidis (2005-07-22) # (HE) Hebrew - Shimi # (BG) Bulgarian - Dimitar (2005-01-24) # last update: elseif (2005-02-19) # (SR_EC) Serbian cyrillic - Sasa Stefanovic (2006-07-22) # (SR_EL) Serbian latin - Sasa Stefanovic (2006-07-22) # (SQ) Albanian - h3li0s # # A list of charsets is at http://www.w3.org/International/O-charset-list.html. ### English mostop1 = "[:nick] donated [:ops] ops in the channel..." mostop2 = "[:nick] was also very polite: [:ops] ops from [:him:her:]." mostop3 = "Strange, no op was given on [:channel]!" mostdeop1 = "[:nick] is the channel sheriff with [:deops] deops." mostdeop2 = "[:nick] deoped [:deops] users." mostdeop3 = "Wow, no op was taken on [:channel]!" mostvoice1 = "[:nick] donated [:voices] voices in the channel..." mostvoice2 = "[:nick] was also very polite: [:voices] voices from [:him:her:]." mostvoice3 = "Strange, no voices were given on [:channel]!" mostdevoice1 = "[:nick] likes taking voice from people, [:devoices] devoices." mostdevoice2 = "[:nick] was close to the same, devoiced [:devoices] users." mostdevoice3 = "No voices were taken on [:channel]!" mosthalfop1 = "[:nick] donated [:halfops] halfops in the channel..." mosthalfop2 = "[:nick] was also very polite: [:halfops] halfops from [:him:her:]." mosthalfop3 = "Strange, no halfop was given on [:channel]!" mostdehalfop1 = "[:nick] is the channel sheriff with [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] dehalfoped [:dehalfops] users." mostdehalfop3 = "Wow, no halfop was taken on [:channel]!" action1 = "[:nick] always lets us know what [:he:she:]'s doing: [:actions] actions!" action2 = "Also, [:nick] tells us what's up with [:actions] actions." action3 = "No actions in [:channel]!" actiontext = "For example, like this:
     [:line]" question1 = "Is [:nick] stupid or just asking too many questions? [:per]% lines contained a question!" question2 = "[:nick] didn't know that much either. [:per]% of [:his:her:] lines were questions." question3 = "Nobody asked questions here; just geniuses in this channel?" shout1 = "The loudest one was [:nick], who yelled [:per]% of the time!" shout2 = "Another old yeller was [:nick], who shouted [:per]% of the time!" shout3 = "Nobody shouted at all, wow." allcaps1 = "It seems that [:nick]'s shift-key is hanging: [:per]% of the time [:he:she:] wrote UPPERCASE." allcaps2 = "[:nick] just forgot to deactivate [:his:her:] Caps-Lock. [:He:She:] wrote UPPERCASE [:per]% of the time." allcaps3 = "Everybody had their shift-key under control. :)" allcapstext = "For example, like this:
     [:line]" violent1 = "[:nick] is a very aggressive person. [:He:She:] attacked others [:attacks] times." violent2 = "[:nick] can't control [:his:her:] aggressions, either. [:He:She:] picked on others [:attacks] times." violent3 = "Nobody beat anyone up. Everybody was friendly." violenttext = "For example, like this:
     [:line]" attacked1 = "Poor [:nick], nobody likes [:him:her:]. [:He:She:] was attacked [:attacks] times." attacked2 = "[:nick] seems to be unliked too. [:He:She:] got beaten [:attacks] times." attackedtext = "For example, like this:
     [:line]" gotkick1 = "[:nick] wasn't very popular, getting kicked [:kicks] times!" gotkick2 = "[:nick] seemed to be hated too: [:kicks] kicks were received." kicktext = "For example, like this:
     [:line]" joins = "[:nick] couldn't decide whether to stay or go. [:joins] joins during this reporting period!" kick1 = "[:nick] is either insane or just a fair op, kicking a total of [:kicked] people!" kick2 = "[:oldnick]'s faithful follower, [:nick], kicked about [:kicked] people." kick3 = "Nice opers here, no one got kicked!" words1 = "[:nick] spoke a total of [:words] words!" words2 = "[:oldnick]'s faithful follower, [:nick], didn't speak so much: [:words] words." words3 = "Nobody said anything... What a strange channel..." mono1 = "[:nick] talks to [:him:her:]self a lot. [:He:She:] wrote over 5 lines in a row [:monos] times!" mono2 = "Another lonely one was [:nick], who managed to hit [:monos] times." wpl1 = "[:nick] wrote an average of [:wpl] words per line." wpl2 = "Channel average was [:avg] words per line." long1 = "[:nick] wrote the longest lines, averaging [:letters] letters per line." long2 = "[:channel] average was [:avg] letters per line." short1 = "[:nick] wrote the shortest lines, averaging [:letters] characters per line." short2 = "[:nick] was tight-lipped, too, averaging [:letters] characters." foul1 = "[:nick] has quite a potty mouth. [:per]% words were foul language." foul2 = "[:nick] also makes sailors blush, [:per]% of the time." foul3 = "Nobody is foul-mouthed in [:channel]! Get out much?" foultext = "For example, like this:
     [:line]" smiles1 = "[:nick] brings happiness to the world. [:per]% lines contained smiling faces. :)" smiles2 = "[:nick] isn't a sad person either, smiling [:per]% of the time." smiles3 = "Nobody smiles in [:channel]! Cheer up guys and girls." sad1 = "[:nick] seems to be sad at the moment: [:per]% lines contained sad faces. :(" sad2 = "[:nick] is also a sad person, crying [:per]% of the time." sad3 = "Nobody is sad in [:channel]! What a happy channel. :-)" month = "January February March April May June July August September October November December" day = "Sunday Monday Tuesday Wednesday Thursday Friday Saturday" ## Topics bignumtopic = "Big numbers" othernumtopic = "Other interesting numbers" latesttopic = "Latest Topics" activetimestopic = "Most active times" activenickstopic = "Most active nicks" activenickbyhourtopic = "Most active nicks by hours" mostwordstopic = "Most used words" referencetopic = "Most referenced nicks" smileytopic = "Smileys :-)" karmatopic = "[:channel] karma" urlstopic = "Most referenced URLs" chartstopic = "[:channel] Music Charts" notopic = "A topic was never set on this channel." mostnickstopic = "Users with most nicknames" bylinetopic = "[:date] at [:time] by [:nick]" dailyactivitytopic = "Daily activity (last [:n] days)" activegenderstopic = "Most active gender" ## Other text totallines = "Total number of lines: [:lines]." totalnicks = "By the way, there were [:totalnicks] other nicks." totaltopic = "The topic was set [:total] times." nick = "Nick" names = "Names Used" url = "URL" numberlines = "Number of lines" randquote = "Random quote" userpic = "Userpic" nottop = "These didn't make it to the top:" word = "Word" numberuses = "Number of Uses" show_words = "Number of Words" show_time = "When?" show_wpl = "Words per line" show_cpl = "Chars per line" show_lastseen = "Last seen" lastused = "Last Used by" smiley = "Smiley" karma = "Karma" goodkarma = "Good karma by" badkarma = "Bad karma by" lastseen1 = "yesterday" lastseen2 = "[:days] days ago" today = "today" pagetitle1 = "[:channel] @ [:network] stats by [:maintainer]" pagetitle2 = "Statistics generated on " pagetitle3 = "During this [:days]-day reporting period, a total of [:nicks] different nicks were represented on [:channel]." stats_gen_by = "Stats generated by [:pisg_url] v[:version]" author = "pisg by [:author_url] and others" stats_gen_in = "Stats generated in [:time]" hours = "hours" minutes = "minutes" seconds = "seconds" and = "and" names1 = "names" names2 = "name" gender = "Gender" gender_f = "Female" gender_m = "Male" gender_b = "Bot" song = "Song" numberplayed = "How Often Played" playedby = "Last Played by" # Mouse-over titles pisghomepage = "Go to the pisg homepage" authorhomepage = "Go to the authors homepage" newwindow = "Open in new window:" mailto = "Mail to"
### German mostop1 = "[:nick] vergab [:ops] Ops im Channel..." mostop2 = "[:nick] war auch sehr zuvorkommend, [:ops] Ops von [:ihm:ihr:]." mostop3 = "Komisch, kein Op wurde in [:channel] vergeben!" mostdeop1 = "[:nick] ist die Channel-Polizei. [:Er:Sie:] hat [:deops] Usern das @ wieder weggenommen..." mostdeop2 = "[:nick] nahm [:deops] Usern das @ wieder weg." mostdeop3 = "Wow, niemand wurde in [:channel] deopped!" mosthalfop1 = "[:nick] empfand sehr viele Leute als hilfreich. [:Er:Sie:] hat [:halfops] Usern ein % verpasst..." mosthalfop2 = "[:nick] verteilte [:halfops] mal Halfop." mosthalfop3 = "Keiner hat in [:channel] bis jetzt ein % bekommen!" mostdehalfop1 = "[:nick] hat am meisten User dehalfopped: genau [:dehalfops] Stück an der Zahl." mostdehalfop2 = "[:nick] hat immerhin schon [:dehalfops] Usern das % wieder geklaut." mostdehalfop3 = "Bis jetzt wurde in [:channel] keinem das % weggenommen!" mostvoice1 = "[:nick] hat [:voices] Voices im Channel vergeben..." mostvoice2 = "[:nick] war auch sehr höflich: [:voices] Voices von [:ihm:ihr:]." mostvoice3 = "Seltsam, bisher wurden keine Voices in [:channel] vergeben!" mostdevoice1 = "[:nick] ist der Wachtmeister des Channels mit [:devoices] entfernten Voices." mostdevoice2 = "[:nick] hat [:devoices] Nutzer devoiced." mostdevoice3 = "Wow, niemandem wurde in [:channel] das Voice genommen!" action1 = "[:nick] hält uns immer auf dem Laufenden, was [:er:sie:] gerade tut: [:actions] Actions!" action2 = "Auch [:nick] verät uns, was los ist: [:actions] Actions von [:ihm:ihr:]." action3 = "Keine Actions in [:channel]!" actiontext = "Zum Beispiel so:
     [:line]" question1 = "[:nick] hat wohl in der Schule nicht gut aufgepasst... [:per]% [:seiner:ihrer:] Zeilen enthielten eine Frage!" question2 = "[:nick] weiss wohl auch nicht viel, [:per]% [:seiner:ihrer:] Zeilen waren Fragen." question3 = "Niemand hat hier was gefragt, sollte das etwa ein Channel voller Genies sein? ;)" shout1 = "Am lautesten war [:nick] [:der:die:] [:per]% der Zeit geschrien hat!" shout2 = "Ein anderer Schreihals war [:nick], [:der:die:] [:per]% der Zeit rumgeschrien hat!" shout3 = "Niemand hat ein Ausrufezeichen benutzt, wow... Zurückhaltende User im Channel ;)" allcaps1 = "Anscheinend klemmte die Shift-Taste von [:nick], denn [:per]% der Zeit schrieb [:er:sie:] in GROSSBUCHSTABEN." allcaps2 = "[:nick] hat auch wohl vergessen CAPS-Lock auszuschalten, von [:ihm:ihr:] kamen [:per]% der Zeit GROSSBUCHSTABEN." allcaps3 = "Alle hatten ihre Shift-Taste gut unter Kontrolle. :)" allcapstext = "Zum Beispiel so:
     [:line]" violent1 = "[:nick] ist etwas agressiv. [:Er:Sie:] schlug [:attacks] mal wild um sich herum." violent2 = "Auch [:nick] hat einige Probleme [:seine:ihre:] Aggressionen unter Kontrolle zu halten, [:attacks] Schläge von [:ihm:ihr:]." violent3 = "Alle waren friedlich im Channel, niemand hat jemanden geschlagen." violenttext = "Zum Beispiel so:
     [:line]" attacked1 = "[:nick] ist der Sündenbock im Channel, [:er:sie:] wurde [:attacks] mal geschlagen." attacked2 = "[:nick] hat auch [:sein:ihr:] Fett weg bekommen, [:er:sie:] hat [:attacks] mal Schläge bekommen." attackedtext = "Zum Beispiel so:
     [:line]" gotkick1 = "[:nick] war wohl der Channelclown, [:er:sie:] wurde [:kicks] mal gekickt!" gotkick2 = "[:nick] konnte sich scheinbar auch nicht benehmen, [:kicks] Kicks für [:ihn:sie:]." kicktext = "Zum Beispiel so:
     [:line]" joins = "[:nick] konnte sich nicht entscheiden im Channel zu bleiben oder zu gehen, [:joins] Joins während des Statistik-Zeitraums!" kick1 = "Ist [:nick] jetzt einfach nur ein fairer Op oder macht [:ihm:ihr:] das Spass? [:Er:Sie:] kickte [:kicked] Personen!" kick2 = "[:oldnick]s würdiger Nachfolger, [:nick], [:er:sie:] kickte [:kicked] User." kick3 = "Nette Opper hier, niemand wurde gekickt!" words1 = "[:nick] war mit [:words] Worten sehr mitteilungsbedürftig!" words2 = "[:oldnick]s würdiger Nachfolger, [:nick], schaffte es auf immerhin [:words] Worte." words3 = "Niemand hat etwas gesagt? Seltsamer Channel..." mono1 = "[:nick] spricht viel mit sich selbst, [:er:sie:] schrieb über 5 Zeilen hintereinander und das [:monos] mal!" mono2 = "Ein anderes einsames Herz ist [:nick], [:der:die:] [:monos] mal mit sich selbst redete." wpl1 = "[:nick] schrieb im Schnitt [:wpl] Worte pro Zeile..." wpl2 = "Der Channeldurchschnitt lag bei [:avg] Worten/Zeile." long1 = "[:nick] ist die Labertasche im Channel. [:Er:Sie:] schrieb die längste Zeile mit durchschnittlich [:letters] Buchstaben pro Zeile." long2 = "Channel-Durchschnitt in [:channel] war [:avg] Buchstaben pro Zeile." short1 = "[:nick] ist nicht sehr mitteilungsbedürftig. [:Er:Sie:] schrieb die kürzeste Zeile mit durchschnittlich [:letters] Buchstaben pro Zeile." short2 = "[:nick] fasste sich auch sehr kurz, durchschnittlich [:letters] Buchstaben pro Zeile." foul1 = "[:nick] hat in [:seiner:ihrer:] Jugend keine Erziehung genossen, [:per]% von dem was [:er:sie:] sagte waren Schimpfworte!" foul2 = "[:nick] war [:per]% der Zeit unartig (Ob da der Weihnachtsmann noch kommt?)" foul3 = "Alle gut erzogen in [:channel], niemand hat Schimpfworte benutzt!" foultext = "Zum Beispiel so:
     [:line]" smiles1 = "[:nick] ist ein fröhlicher Mensch, [:per]% [:seiner:ihrer:] Zeilen enthielt ein fröhliches Smily :)" smiles2 = "[:nick] scheint auch glücklich zu sein. [:Er:Sie:] lächelte [:per]% der Zeit." smiles3 = "Niemand lächelt in [:channel]! Los Leute, legt mal wieder ein Lächeln auf :)" sad1 = "[:nick] scheint im Moment nicht gut drauf zu sein, [:per]% [:seiner:ihrer:] Zeilen enthielten ein trauriges Smily :(" sad2 = "[:nick] ist auch eine traurige Person, die [:per]% der Zeit geweint hat." sad3 = "Niemand ist traurig in [:channel]! Was für ein fröhlicher Channel :)" month = "Januar Februar März April Mai Juni Juli August September Oktober November Dezember" day = "Sonntag Montag Dienstag Mittwoch Donnerstag Freitag Samstag" ## Topics bignumtopic = "Die Zahlen sprechen für sich :)" othernumtopic = "Andere interessante Zahlen" latesttopic = "Letzte Topics" activetimestopic = "Wann war am meisten los?" activenickstopic = "Wer quatscht am meisten?" activenickbyhourtopic = "Wer war wann am aktivsten?" mostwordstopic = "Am meisten benutzte Wörter" referencetopic = "Begehrte Nicks :)" smileytopic = "Smileys :-)" karmatopic = "[:channel]-Karma" urlstopic = "Am meisten benutzte URLs" chartstopic = "Ohrwürmer auf [:channel]" notopic = "In diesem Channel wurde kein Topic gesetzt." bylinetopic = "[:date] um [:time] von [:nick]" dailyactivitytopic = "Tägliche Aktivität (letzte [:n] Tage)" mostnickstopic = "Chatter mit den meisten Nicks" activegenderstopic = "Aktivste Geschlechter" ## Other text totallines = "Gesamtanzahl der Zeilen: [:lines]" totalnicks = "Ach ja, da waren noch [:totalnicks] andere, die nicht erwähnenswert sind." totaltopic = "Ingesamt wurde das Topic [:total] mal gesetzt." nick = "Nick" names = "Benutzte Namen" url = "URL" numberlines = "Anzahl der Zeilen" randquote = "Zufallsquote" userpic = "Userbild" nottop = "Sie haben es nicht an die Spitze geschafft:" word = "Wort" show_words = "Anzahl der Worte" show_time = "Wann?" show_wpl = "Worte pro Zeile" show_cpl = "Zeichen pro Zeile" numberuses = "Wie oft benutzt" show_lastseen = "Zuletzt gesehen" lastused = "Zuletzt benutzt von" smiley = "Smiley" karma = "Karma" goodkarma = "Gutes Karma von" badkarma = "Schleches Karma von" lastseen1 = "gestern" lastseen2 = "vor [:days] Tagen" today = "heute" pagetitle1 = "[:channel] @ [:network]-Statistik von [:maintainer]" pagetitle2 = "Statistik erstellt am " pagetitle3 = "Während des Statistikzeitraums von [:days] Tage(n) wurden [:nicks] verschiedene Nicks in [:channel] gezählt." stats_gen_by = "Die Statistik wurde mit [:pisg_url] v[:version] erstellt." author = "pisg von [:author_url] und anderen" stats_gen_in = "Die Statistik wurde in [:time] generiert." hours = "Stunden" minutes = "Minuten" seconds = "Sekunden" and = "und" names1 = "Nicks" names2 = "Nick" gender = "Geschlecht" gender_f = "Weiblich" gender_m = "Männlich" gender_b = "Bot" song = "Song" numberplayed = "Wie oft gespielt" playedby = "Zuletzt gespielt von" # Mouse-over titles pisghomepage = "pisg-Homepage öffnen" authorhomepage = "Homepage des Autors öffnen" newwindow = "In einem neuen Fenster öffnen:" mailto = "Mail an"
### Danish mostop1 = "[:nick] gav [:ops] op status i kanalen..." mostop2 = "[:nick] var også venlig at gi': [:ops] fra sig" mostop3 = "Underligt, ingen har fået op på [:channel] endnu!" mostdeop1 = "[:nick] holder orden på [:channel] med [:deops] deops..." mostdeop2 = "[:nick] deoppede [:deops] brugere" mostdeop3 = "Hmm, der var ingen som blev deopped på [:channel]!" mostvoice1 = "[:nick] gav [:voices] voice i kanalen..." mostvoice2 = "[:nick] var også venlig at gi': [:voices] fra sig" mostvoice3 = "Underligt, ingen har fået voice på [:channel] endnu!" mostdevoice1 = "[:nick] holder orden på [:channel] med [:devoices] -v's" mostdevoice2 = "[:nick] devoicede [:devoices] brugere" mostdevoice3 = "Hmm, der var ingen som blev devoiced på [:channel]!" mosthalfop1 = "[:nick] gav [:halfops] halfop status i kanalen..." mosthalfop2 = "[:nick] var også venlig at gi': [:halfops] halfops fra sig" mosthalfop3 = "Underligt, ingen har fået halfop på [:channel]!" mostdehalfop1 = "[:nick] er kanal sheriffen med [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] fjernede halfop fra [:dehalfops] brugere." mostdehalfop3 = "Wow, ingen halfop blev taget fra nogen på [:channel]!" action1 = "[:nick] bruger /me meget tit, ialt [:actions] gange!" action2 = "[:nick] fortæller os også hvad [:han:hun:] laver.. [:actions] /me's" action3 = "Ingen /me's i [:channel] !" actiontext = "For eksempel sådan her:
     [:line]" question1 = "[:nick] må være rimelig dum eller efterligner bare Spørge-Jørgen... [:per]% af [:hans:hendes:] linjer var spørgsmål!" question2 = "[:nick] var heller ingen Einstein, [:per]% af [:hans:hendes:] linjer var også spørgsmål" question3 = "Ingen spørgsmål på denne kanal. De må sørme være kloge!" shout1 = "Den mest larmende var [:nick], som råbte [:per]% af tiden!" shout2 = "En anden skrigehals var [:nick], som råbte [:per]% af tiden!" shout3 = "Der er ingen som råber. Leger de stilleleg?" gotkick1 = "[:nick] er ret upopulær, blev sparket ud [:kicks] gange!" gotkick2 = "[:nick] er heller ikke nogen Elvis, [:kicks] gange fik [:han:hun:] sparket" kicktext = "F.eks. sådan her:
     [:line]" joins = "[:nick] er lidt forvirret. [:Han:Hun:] har været inde og ude af kanalen [:joins] gange!" kick1 = "[:nick] er magtsygt eller ved hvordan [:han:hun:] skal kontrollere sine fjender. [:Han:Hun:] har sparket [:kicked] folk ud af kanalen!" kick2 = "[:oldnick] har en efterfølger. [:nick] sparkede [:kicked] folk ud af kanalen" kick3 = "Venlige operatører må man sige. Ingen har fået sparket!" mono1 = "[:nick] snakker meget med sig selv. [:Han:Hun:] har skrevet over 5 linjer på en gang, [:monos] gange!" mono2 = "En anden ensom person var [:nick], som snakkede til sig selv [:monos] gange" wpl1 = "[:nick] skrev i gennemsnit [:wpl] ord pr. linje.." wpl2 = "Kanalens gennemsnit var [:avg] ord pr. linje." long1 = "[:nick] skriver meget lange sætninger. Gennemsnittet var [:letters] bogstaver pr. linje..." long2 = "Gennemsnittet på [:channel] er [:avg] bogstaver pr. linje" short1 = "[:nick] skrev de korteste linjer. Gennemsnittet er [:letters] bogstaver pr. linje..." short2 = "[:nick] skriver også korte linjer, med et gennesnit på [:letters]" foul1 = "[:nick] er lidt stor i munden, [:per]% af ordene var uhøfligt sprog" foul2 = "[:nick] burde også vaske munden med sæbe med alt det [:han:hun:] fyrer af, [:per]% af tiden" foul3 = "Ingen rapkæftede på [:channel]!" foultext = "For eksempel sådan her:
     [:line]" smiles1 = "[:nick] er altid glad, [:per]% af linjerne havde glade ansigter :)" smiles2 = "[:nick] er heller ikke en trist person, som smilede [:per]% af tiden" smiles3 = "Ingen smiler på [:channel]! Op med humøret drenge og piger." sad1 = "[:nick] er meget ked af det for tiden, [:per]% af linjerne havde sørgelige ansigter :(" sad2 = "[:nick] er også en trist person, som græd [:per]% af tiden" sad3 = "Ingen er kede af det på [:channel]! Sikke en glad kanal :-)" allcaps1 = "Ser ud til at [:nick] har en voldsom trang til at råbe konstant, [:per]% af de gange [:han:hun:] skrev var med stort" allcaps2 = "[:nick] glemte vidst at Caps-Lock var slået til, [:per]% af de gange [:han:hun:]han skrev var med stort" allcaps3 = "Ser ud til at alle har deres shift under kontrol :)" allcapstext = "For eksempel sådan her:
     [:line]" violent1 = "[:nick] er en meget aggresiv person, [:han:hun:] delte [:attacks] slaps ud." violent2 = "[:nick] er ude af kontrol. [:Han:Hun:] slog andre folk [:attacks] gang(e)." violent3 = "Alle er glade ... endnu 8)" violenttext = "For eksempel sådan her:
     [:line]" attacked1 = "Ærgeligt. Ingen kan li' [:nick]. [:Han:Hun:] blev banket [:attacks] gange." attacked2 = "[:nick] er vidst heller ikke for polulær, [:han:hun:] fik tæsk [:attacks] gang(e)." attackedtext = "For eksempel sådan her:
     [:line]" words1 = "[:nick] er meget aktiv med [:words] skrevne ord!" words2 = "[:oldnick] blev tæt forfulgt af [:nick], med [:words] ord." words3 = "Hmmm ingen har sagt noget endnu... underlig kanal..." month = "Januar Februar Marts April Maj Juni Juli August September Oktober November December" day = "Søndag Mandag Tirsdag Onsdag Torsdag Fredag Lørdag" ## Topics bignumtopic = "Store numre" othernumtopic = "Andre interessante numre" latesttopic = "Sidst nyeste topics" activetimestopic = "Mest aktive tider" activenickstopic = "Mest aktive nicks" activenickbyhourtopic = "Mest aktive nicks i timer" mostwordstopic = "Mest brugte ord" referencetopic = "Mest tiltalte nicks" karmatopic = "[:channel] karma" urlstopic = "Mest brugte URLs" notopic = "Et topic blev aldrig sat på denne kanal." mostnickstopic = "Brugere med flest nicks" bylinetopic = "[:date] kl. [:time] af [:nick]" dailyactivitytopic = "Daglig aktivitet (sidste [:n] dage)" activegenderstopic = "Mest aktive køn" smileytopic = "Smiley'er :-)" chartstopic = "[:channel] Musik hitliste" ## Other text totallines = "Hele antal linjer: [:lines]" totalnicks = "Forresten var der [:totalnicks] andre nicks" totaltopic = "Topic'et blev sat [:total] gange" nick = "Nick" names = "Navne Brugt" url = "URL" numberlines = "Antal linjer" randquote = "Tilfældig sætning" userpic = "Brugerbillede" nottop = "Disse nåede ikke til tops:" word = "Ord" numberuses = "Antal forbrug" show_words = "Antal af ord" show_time = "Hvornår?" show_wpl = "Ord pr. linje" show_cpl = "Bogstaver pr. linje" show_lastseen = "Sidst set" lastused = "Sidst brugt af" karma = "Karma" goodkarma = "God karma af" badkarma = "Dårlig karma af" lastseen1 = "i går" lastseen2 = "[:days] dage siden" today = "I dag" pagetitle1 = "[:channel] @ [:network] statistikker af [:maintainer]" pagetitle2 = "Statistikker genereret " pagetitle3 = "Igennem denne [:days]-dages periode, har der været [:nicks] forskellige nicks på [:channel]." stats_gen_by = "Stats genereret af [:pisg_url] v[:version]" author = "pisg af [:author_url] og andre" stats_gen_in = "Stats genereret på [:time]" hours = "timer" minutes = "minutter" seconds = "sekunder" and = "og" names1 = "nicks" names2 = "nick" gender = "Køn" gender_f = "Hun" gender_m = "Han" gender_b = "Bot" numberplayed = "Hvor ofte spillet" song = "Sang" playedby = "Sidst spillet af" smiley = "Smiley" # Mouse-over titles pisghomepage = "Gå til pisg hjemmesiden" authorhomepage = "Gå til forfatterens hjemmeside" newwindow = "Åben i nyt vindue:" mailto = "Mail til"
### French mostop1 = "[:nick] a donné [:ops] ops sur le canal..." mostop2 = "[:nick] est aussi très poli[::e:(e):] : [:ops] ops de sa part." mostop3 = "Étrange, aucun op n'a été donné sur [:channel] !" mostdeop1 = "[:nick] est l[:e:a:e:] sherif du canal avec [:deops] deops..." mostdeop2 = "[:nick] a déopé [:deops] utilisateurs." mostdeop3 = "Wow, aucun op n'a été retiré sur [:channel] !" mosthalfop1 = "[:nick] a donné [:halfops] halfops sur le canal..." mosthalfop2 = "[:nick] est aussi très poli[::e:(e):] : [:halfops] halfops de sa part." mosthalfop3 = "Étrange, aucun halfop n'a été donné sur [:channel] !" mostdehalfop1 = "[:nick] est l[:e:a:] sherif du canal avec [:dehalfops] dehalfops..." mostdehalfop2 = "[:nick] a dehalfopé [:dehalfops] utilisateurs." mostdehalfop3 = "Wow, aucun halfop n'a été retiré sur [:channel] !" mostvoice1 = "[:nick] a donné [:voices] fois le +v sur le canal..." mostvoice2 = "[:nick] est aussi très poli[::e:(e):]: [:voices] +v de sa part." mostvoice3 = "C'est curieux, on n'a jamais donné un seul +v sur [:channel] !" mostdevoice1 = "[:nick] est l[:e:a:] sherif du canal avec [:devoices] -v." mostdevoice2 = "[:nick] a dévoicé [:devoices] personnes." mostdevoice3 = "Wow, aucun +v n'a été retiré sur [:channel] !" action1 = "[:nick] aime bien faire savoir ce qu'[:il:elle:] fait, avec [:actions] actions !" action2 = "Egalement [:nick] qui n'est pas en reste avec [:actions] actions !" action3 = "Aucune action sur [:channel] !" actiontext = "Exemple :
     [:line]" question1 = "[:nick] est soit stupide soit trop curieu[:x:se:x(se):]... [:per]% de ses lignes contiennent une question !" question2 = "[:nick] n'en connait pas davantage, [:per]% de ses lignes étaient des questions." question3 = "Personne ne pose de question ici, tous des génies sur ce canal ?" shout1 = "[:Le:La:] plus bruyant[::e:(e):] est [:nick] qui gueule [:per]% du temps !" shout2 = "[:nick] est aussi un[::e:(e):] [:vieux raleur:mégère:] qui braille [:per]% du temps !" shout3 = "Personne ne s'exclame ici, wow." allcaps1 = "Il semblerait que le CAPS-LOCK soit bloqué chez [:nick], qui écrit en majuscules [:per]% du temps." allcaps2 = "[:nick] a oublié de désactiver son CAPS-LOCK, qui écrit en majuscules [:per]% du temps." allcaps3 = "Tous les CAPS-LOCK sont sous contrôle :)" allcapstext = "Exemple :
     [:line]" violent1 = "[:nick] est une personne agressive, qui a déja donné [:attacks] tapes à quelqu'un." violent2 = "[:nick] ne peut contrôler son agressivité, en tapant [:attacks] fois quelqu'un." violent3 = "Personne ne se donne des tapes, tout le monde est sympa." violenttext = "Exemple :
     [:line]" attacked1 = "Pauvre [:nick], personne ne l'aime, en étant tapé[::e:(e):] [:attacks] fois." attacked2 = "[:nick] n'a pas l'air apprécié[::e:(e):] non plus, qui a déjà été tapé[::e:(e):] [:attacks] fois." attackedtext = "Exemple :
     [:line]" gotkick1 = "[:nick] n'est pas très populaire, kické[::e:(e):] [:kicks] fois !" gotkick2 = "[:nick] n'a pas d'ami non plus, [:kicks] kicks reçus." kicktext = "Exemple :
     [:line]" joins = "Rester ou partir est un choix difficile : [:nick] a fait [:joins] visites durant cette période !" kick1 = "[:nick] est malade ou alors aime bien jouer, son kick a sévi [:kicked] fois !" kick2 = "Un[::e:] disciple de [:oldnick], [:nick] a kické [:kicked] personnes." kick3 = "Les ops sont sympas ici, personne n'a été kické !" words1 = "[:nick] a dit un total de [:words] mots !" words2 = "Et juste derrière [:oldnick], [:nick], avec quand même [:words] mots à son actif." words3 = "Personne ne dit rien... Quel canal étrange..." mono1 = "[:nick] se parle tout[::e:(e):] seul[::e:(e):] très souvent, en écrivant plus de 5 lignes d'un coup à [:monos] reprises !" mono2 = "Un[::e:(e):] autre incompris[::e:(e):] est [:nick], qui a tenté de se prendre la tête à [:monos] reprises." wpl1 = "[:nick] écrit en moyenne [:wpl] mots par ligne..." wpl2 = "La moyenne du canal est de [:avg] mots par ligne." long1 = "[:nick] a écrit des lignes bien longues ! [:letters] lettres par ligne !" long2 = "La moyenne sur [:channel] est de [:avg] lettres par ligne." short1 = "[:nick] a écrit les lignes les plus courtes, avec en moyenne [:letters] lettres par ligne..." short2 = "[:nick] n'a pas grand chose à dire non plus, en moyenne [:letters]." foul1 = "[:nick] est bien vulgaire, [:per]% de ses mots étaient des gros mots." foul2 = "[:nick] parle aussi comme un charretier, [:per]% du temps." foul3 = "Personne n'est grossier sur [:channel] ! Pendant combien de temps encore ?" foultext = "Exemple :
     [:line]" smiles1 = "[:nick] apporte un peu de gaieté dans le monde, [:per]% de ses lignes contiennent un smiley :)" smiles2 = "[:nick] n'est pas triste non plus, qui sourit [:per]% du temps." smiles3 = "Personne ne sourit sur [:channel] ! Allez faites un effort quoi !" sad1 = "[:nick] semble un peu déprimé[::e:(e):] en ce moment, [:per]% de ses lignes contiennent un smiley :(" sad2 = "[:nick] est aussi bien triste, en pleurant [:per]% du temps." sad3 = "Personne n'est triste sur [:channel] ! Quel canal merveilleux :-)" month = "janvier février mars avril mai juin juillet août septembre octobre novembre décembre" day = "Dimanche Lundi Mardi Mercredi Jeudi Vendredi Samedi" ## Topics bignumtopic = "Les gros chiffres" othernumtopic = "D'autres chiffres intéressants" latesttopic = "Les derniers topics" activetimestopic = "Les périodes d'intense activité" activenickstopic = "Les nicks les plus actifs" activenickbyhourtopic = "Les nicks les plus actifs par heure" mostwordstopic = "Les mots les plus utilisés" referencetopic = "Les nicks les plus utilisés dans la conversation" smileytopic = "Smileys :-)" karmatopic = "Le karma de [:channel]" urlstopic = "Les URLs les plus citées" notopic = "Il n'y a jamais eu de topic sur ce canal" mostnickstopic = "Ceux qui ont le plus de nicks" bylinetopic = "[:date] par [:nick] à [:time]" dailyactivitytopic = "Activité journalière (des [:n] derniers jours)" activegenderstopic = "Le sexe dominant" chartstopic = "[:channel] Hit parade des chansons" ## Other text totallines = "Nombre total de lignes: [:lines]" totalnicks = "Il y a également eu [:totalnicks] autres nicks sur le canal" totaltopic = "Il y a eu [:total] topics différents sur le canal" nick = "Nick" names = "Les différents nicks utilisés" url = "URL" numberlines = "Nb de lignes" randquote = "Citation typique" userpic = "Image" nottop = "Ne sont pas dans le classement" word = "Mot" numberuses = "Nb d'occurences" show_words = "Nb de Mots" show_time = "Quand ?" show_wpl = "Mots par ligne" show_cpl = "Lettres par ligne" show_lastseen = "Dernière venue" lastused = "Dernière utilisation par" smiley = "Smiley" karma = "Karma" goodkarma = "Bon karma par" badkarma = "Mauvais karma par" lastseen1 = "hier" lastseen2 = "avant [:days] jours" today = "Aujourd'hui" pagetitle1 = "[:channel] @ [:network] stats par [:maintainer]" pagetitle2 = "Statistiques générées le " pagetitle3 = "Durant cette période de [:days] jours, [:nicks] nicks différents sont apparus sur [:channel]." stats_gen_by = "Stats générées par [:pisg_url] v[:version]" author = "pisg de [:author_url] et autres" stats_gen_in = "Stats générées en [:time]" hours = "heures" minutes = "minutes" seconds = "secondes" and = "et" names1 = "noms" names2 = "nom" gender = "Sexe" gender_f = "Femme" gender_m = "Homme" gender_b = "Bot" numberplayed = "Jouée combien de fois" song = "Chanson" playedby = "Jouée la dernière fois par" # Mouse-over titles pisghomepage = "Aller sur le site de pisg" authorhomepage = "Aller sur le site de l'auteur" newwindow = "Ouvrir dans une nouvelle fenêtre :" mailto = "Envoyer un mail"
### Spanish mostop1 = "[:nick] ha dado [:ops] ops en el canal..." mostop2 = "[:nick] también reparte ensaimadas: [:ops] nada menos." mostop3 = "¡Aún no se han repartido arrobas en [:channel]!" mostdeop1 = "[:nick] es el malo del canal, le ha quitado la @ a [:deops] personas." mostdeop2 = "[:nick] le ha quitado la @ a [:deops] personas." mostdeop3 = "¡Por el momento no se le ha quitado la arroba a nadie en [:channel]!" mostvoice1 = "[:nick] ha dado [:voices] +v en el canal..." mostvoice2 = "[:nick] también repartió [:voices] +v." mostvoice3 = "¡Aún no se han concedido +v en [:channel]!" mostdevoice1 = "[:nick] disfruta quitándole a la gente su +v, en [:devoices] ocasiones." mostdevoice2 = "[:nick] es de la misma calaña, se lo hizo a [:devoices] personas." mostdevoice3 = "¡Nadie quitó +v en [:channel]!" mosthalfop1 = "[:nick] ha dado [:halfops] halfops en el canal..." mosthalfop2 = "[:nick] también repartió [:halfops] halfops." mosthalfop3 = "¡Todavía no se han repartido halfop en [:channel]!" mostdehalfop1 = "[:nick] parece el jefe del canal, elimino halfop a [:dehalfops] personas." mostdehalfop2 = "[:nick] debe ser su fan, también lo hizo [:dehalfops] veces." mostdehalfop3 = "¡Increible, la gente no quita halfop en [:channel]!" question1 = "[:nick] necesitaba más horas de guardería cuando era pequeño/a, ¡el [:per]% de sus líneas contienen una pregunta!" question2 = "[:nick] tampoco se entera de mucho, el [:per]% de sus líneas son preguntas." question3 = "Nadie hace preguntas aquí, ¡esto parece un canal de genios!" shout1 = "Me parece que [:nick] está algo exaltado/a. ¡Escribe con exclamaciones el [:per]% del tiempo!" shout2 = "A [:nick] también le gusta afirmar con rotundidad lo que dice. ¡Escribe con exclamaciones el [:per]% del tiempo!" shout3 = "Nadie ha escrito frases con exclamaciones." allcaps1 = "A [:nick] se le ha atascado el bloqueo de mayúsculas, el [:per]% del tiempo escribe CON ESTE ESTILO TAN PECULIAR." allcaps2 = "[:nick] debe tener vicio con la tecla shift, el [:per]% del tiempo hace lo mismo." allcaps3 = "Todo el mundo tiene su tecla shift bajo control :)" allcapstext = "Como por ejemplo, esto:
     [:line]" violent1 = "[:nick] es el/la más agresivo/a del canal, ha repartido tortas [:attacks] veces." violent2 = "[:nick] tiene la mano floja. Ha repartido tortas [:attacks] veces." violent3 = "Nadie ha repartido tortas en este canal, todo el mundo parece amigable." violenttext = "Como muestra:
     [:line]" attacked1 = "Pobre [:nick], No le gusta a nadie. Ha sido abofeteado/a [:attacks] veces." attacked2 = "[:nick] tiene marcas de dedos en la cara. Ha sido abofeteado/a [:attacks] veces." attackedtext = "Ejemplo:
     [:line]" gotkick1 = "[:nick] ha sido algo capullo/a y por eso lo/la echamos [:kicks] veces!" gotkick2 = "[:nick] también nos toca bastante las narices, por eso lo/la echamos [:kicks] veces" joins = "[:nick] no sabe si irse o quedarse, lo/la he visto [:joins] veces entrando en el canal!" kick1 = "[:nick] actúa como operador/a con mano dura, ¡ha echado a [:kicked] personas!" kick2 = "[:oldnick] tiene un seguidor acérrimo, [:nick] ha echado a [:kicked] personas." kick3 = "Es maja la gente de aquí, ¡nadie ha sido kickeado!" kicktext = "Aquí está la prueba:
     [:line]" action1 = "[:nick] quiere mantenernos informados de lo que hace en todo momento. ¡Ha escrito [:actions] acciones!" action2 = "Y por supuesto [:nick] también nos los ha dicho [:actions] veces." action3 = "¡No se han mostrado acciones en [:channel]!" actiontext = "Aquí va un ejemplo:
     [:line]" words1 = "¡[:nick] ha dicho un total de [:words] palabras!" words2 = "El mayor fan de [:oldnick] es [:nick], que ha escrito [:words] palabras." words3 = "Nadie dice nada... que canal más misterioso..." wpl1 = "[:nick] Ha escrito una media de [:wpl] palabras por línea..." wpl2 = "La media del canal es de [:avg] palabras por línea." mono1 = "[:nick] no tiene amigos, ha escrito más de 5 líneas seguidas en [:monos] ocasiones!" mono2 = "Otra persona solitaria es [:nick], que ha hecho lo mismo [:monos] veces." long1 = "[:nick] escribe las líneas más largas: [:letters] letras por línea..." long2 = "La media de [:channel] es de [:avg] letras por línea." short1 = "[:nick] es la persona más vaga escribiendo, con una media de [:letters] letras por línea..." short2 = "[:nick] no se queda atrás, con una media de [:letters] letras." foul1 = "[:nick] necesita que le laven la boca con jabón lagarto, un [:per]% de sus líneas contienen palabrotas y tacos." foul2 = "[:nick] también es algo bestia, dice tacos el [:per]% del tiempo." foul3 = "Parece que todo el mundo habla correctamente en [:channel]! ¿Se desahogan fuera?" foultext = "Por ejemplo, como esto:
     [:line]" smiles1 = "[:nick] parece que se hubiera fumado una compresa usada, el [:per]% de sus líneas contienen caritas sonrientes :)" smiles2 = "[:nick] habrá fumado otra cosa, está sonriendo el [:per]% del tiempo." smiles3 = "¡Nadie ha sonreído en [:channel]! ¡¡Arriba esos ánimos!!" sad1 = "[:nick] parece disgustado, el [:per]% de sus líneas contienen caras tristes :(" sad2 = "[:nick] también está triste el [:per]% del tiempo." sad3 = "Nadie está triste en [:channel]! Aquí somos todos felices :)" month = "Enero Febrero Marzo Abril Mayo Junio Julio Agosto Septiembre Octubre Noviembre Diciembre" day = "Domingo Lunes Martes Miércoles Jueves Viernes Sábado" ## Topics bignumtopic = "Acerca de nuestra gente" othernumtopic = "Otras cosas interesantes" latesttopic = "Últimos Topics" activetimestopic = "Horas más frecuentadas" activenickstopic = "La gente que más habla" activenickbyhourtopic = "La gente que más habla por horas" mostwordstopic = "Las palabras más utilizadas" referencetopic = "Las personas de las que más se habla" karmatopic = "Karma de [:channel]" urlstopic = "URLs más frecuentemente mencionados" notopic = "Aún no se ha utilizado el topic del canal" bylinetopic = "por [:nick] a las [:time]" dailyactivitytopic = "Actividad diaria ([:n] últimos días)" mostnickstopic = "La gente que más nicks usa" activegenderstopic = "Sexo más activo" smileytopic = "Emoticonos :-)" chartstopic = "[:channel] Éxitos musicales" ## Other text totallines = "Número total de líneas: [:lines]" totalnicks = "Ha habido otros [:totalnicks] nicks que han pasado por el canal" totaltopic = "Ha habido [:total] cambios de topic" nick = "Nick" names = "Nombres usados" url = "URL" numberlines = "Líneas" randquote = "Frase al azar" userpic = "Avatar" nottop = "Ellos también están, aunque hablan menos:" word = "Palabra" show_wpl = "Palabras por línea" show_cpl = "letras por línea" show_lastseen = "Visto por última vez" show_time = "Hora" numberuses = "Número de usos" show_words = "palabras" lastused = "Usada por última vez" lastseen1 = "día atrás" lastseen2 = "días atrás" karma = "Karma" goodkarma = "Karma positivo por" badkarma = "Karma negativo por" today = "Hoy" pagetitle1 = "[:channel] @ [:network] estadísticas por [:maintainer]" pagetitle2 = "Estadísticas generadas en " pagetitle3 = "Durante los [:days] días de estadísticas, [:nicks] nicks distintos han pasado por [:channel]." stats_gen_by = "Estadísticas generadas con [:pisg_url] v[:version]" author = "creado por [:author_url] y otros" stats_gen_in = "Estadísticas generadas en [:time]" hours = "horas" minutes = "minutos" seconds = "segundos" and = "y" names1 = "nombres" names2 = "nombre" gender = "Sexo" gender_f = "Mujer" gender_m = "Hombre" gender_b = "Bot" smiley = "Emoticono" numberplayed = "Veces escuchada" song = "Canción" playedby = "Tocada última vez por" # Mouse-over titles pisghomepage = "Página de pisg" authorhomepage = "Página de los autores" newwindow = "Abrir en ventana nueva:" mailto = "Enviar a"
### Polish mostop1 = "[:nick] lubi rozdawać opy robiÄ…c to [:ops] razy..." mostop2 = "Kolejnym dobroczyÅ„cÄ… jest [:nick] - zyskuje popularność nadajÄ…c [:ops] opów." mostop3 = "Dziwne, nikt nie dostaÅ‚ opa na [:channel]!" mostdeop1 = "[:nick] jest kanaÅ‚owym szeryfem odbierajÄ…c [:deops] opów..." mostdeop2 = "[:nick] zdeopowaÅ‚[::a:] [:deops] ircowników." mostdeop3 = "Wow, żaden op nie zostaÅ‚ odebrany na [:channel]!" mostvoice1 = "[:nick] lubi rozdawać voice'y robiÄ…c to [:voices] razy..." mostvoice2 = "[:nick] również byÅ‚[::a:] bardzo uprzejm[:y:a:]: rozdaÅ‚[::a:] [:voices] voice'ów" mostvoice3 = "Dziwne, nikt nie dostaÅ‚ voice'a na [:channel]!" mostdevoice1 = "[:nick] lubi zabierać ludziom voice'y, [:devoices] devoice'ów." mostdevoice2 = "[:nick] ma prawie taki sam wynik, zabraÅ‚[::a:] voice'y [:devoices] ircownikom." mostdevoice3 = "Å»aden voice nie zostaÅ‚ odebrany na [:channel]!" action1 = "[:nick] zawsze mówi nam co robi: [:actions] „akcjiâ€!" action2 = "Również [:nick] mówi nam co jest grane. [:actions] „akcjiâ€." action3 = "Nie byÅ‚o żadnych „akcji†na kanale [:channel]!" actiontext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" mosthalfop1 = "[:nick] rozdaÅ‚[::a:] [:halfops] halfopów na kanale..." mosthalfop2 = "[:nick] również byÅ‚[::a:] bardzo uprzejm[:y:a:]: rozdaÅ‚[::a:] [:halfops] halfopów." mosthalfop3 = "Dziwne, nikt nie dostaÅ‚ halfopa na [:channel]!" mostdehalfop1 = "[:nick] jest kanaÅ‚owym szeryfem odbierajÄ…c [:dehalfops] halfopów..." mostdehalfop2 = "[:nick] zdeopowaÅ‚[::a:] [:dehalfops] ircowników." mostdehalfop3 = "Wow, nikt nikomu nie odebraÅ‚ halfopa na [:channel]!" question1 = "[:nick] jest gÅ‚upi[::a:] albo zadaje zbyt wiele pytaÅ„... [:per]% linii zawieraÅ‚o pytania!" question2 = "[:nick] też nie wie zbyt wiele, [:per]% linii byÅ‚o pytaniami." question3 = "Nikt o nic nie pyta na kanale - czyżby sami geniusze?" shout1 = "NajwiÄ™kszym kanaÅ‚owym krzykaczem jest [:nick], wykrzykiwaÅ‚[::a:] przez [:per]% czasu." shout2 = "Na dalszej pozycji plasuje siÄ™ [:nick], któr[:y:a:] krzyczaÅ‚[::a:] przez [:per]% czasu." shout3 = "Wow, nikt nie krzyczaÅ‚, wszyscy jacyÅ› tacy spokojni..." allcaps1 = "Wydawać by siÄ™ mogÅ‚o, że [:nick] ma zaciÄ™tego shifta, [:per]% czasu używaÅ‚[::a:] wielkich liter." allcaps2 = "[:nick] za to zapomniaÅ‚[::a:] wyłączyć Caps-Locka, [:per]% czasu używaÅ‚[::a:] wielkich liter." allcaps3 = "Wszyscy posiadajÄ… kontrolÄ™ nad swoimi shiftami :)" allcapstext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" violent1 = "[:nick] jest bardzo agresywnÄ… osobÄ…, atakowaÅ‚[::a:] okoÅ‚o [:attacks] razy." violent2 = "[:nick] nie potrafi kontrolować swojej agresji. ZaczepiaÅ‚[::a:] innych okoÅ‚o [:attacks] razy." violent3 = "Nikt nikogo nie atakowaÅ‚, wszyscy zachowywali siÄ™ przyjaźnie." violenttext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" attacked1 = "Biedn[:y:a:] [:nick], nikt [:go:jej:] nie lubi. ByÅ‚[::a:] atakowan[:y:a:] [:attacks] razy." attacked2 = "[:nick] wydaje siÄ™ też nie być zbyt lubian[:y:a:], zaczepiali [:go:jÄ…:] [:attacks] razy." attackedtext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" gotkick1 = "[:nick] nie zaÅ‚apaÅ‚[::a:] o co chodziÅ‚o opom za pierwszym razem i zostaÅ‚[::a:] wykopan[:y:a:] [:kicks] razy!" gotkick2 = "[:nick] nie jest tu chyba zbyt lubian[:y:a:] - wylatywaÅ‚[::a:] [:kicks] razy." kicktext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" joins = "[:nick] nie [:mógÅ‚:mogÅ‚a:] siÄ™ zdecydować czy zostać, [:joins] razy wchodziÅ‚[::a:] na kanaÅ‚!" kick1 = "[:nick] jest szalony lub stara siÄ™ być konsekwentny, wykopaÅ‚[::a:] [:kicked] osob(y)." kick2 = "[:nick], idÄ…c w Å›lad za [:oldnick], wykopaÅ‚[::a:] [:kicked] osob(y)." kick3 = "Mamy tutaj miÅ‚ych operatorów, nikt nie zostaÅ‚ wykopany!" words1 = "[:nick] powiedziaÅ‚[::a:] łącznie [:words] słów!" words2 = "PróbujÄ…c[:y:a:] go dogonić [:nick], nie powiedziaÅ‚[::a:] zbyt wiele, tylko [:words] słów." words3 = "Nikt nic nie mówi... co za dziwny kanaÅ‚!" wpl1 = "[:nick] pisaÅ‚[::a:] Å›rednio [:wpl] słów na linie." wpl2 = "Åšrednia kanaÅ‚u to [:avg] słów na linie." mono1 = "[:nick] uwielbia mówić sam[::a:] do siebie albo inni za [:nim:niÄ…:] nie nadążajÄ…, pisaÅ‚[::a:] monologi [:monos] razy!" mono2 = "Kolejnym samotnikiem okazaÅ‚[::a:] siÄ™ [:nick], któr[:y:a:] pisaÅ‚[::a:] bez towarzystwa [:monos] razy" long1 = "[:nick] pisaÅ‚[::a:] najdÅ‚uższe linie o Å›redniej dÅ‚ugoÅ›ci [:letters] liter..." long2 = "Åšrednia dla kanaÅ‚u [:channel] to [:avg] liter w linii." short1 = "[:nick] staraÅ‚[::a:] siÄ™ pisać zwieźle, Å›rednio [:letters] liter w linii..." short2 = "[:nick] wybÄ…kiwaÅ‚[::a:] krótkie wypowiedzi Å›rednio po [:letters] liter." foul1 = "[:nick] ma niewyparzonÄ… gÄ™bÄ™, [:per]% linii zawieraÅ‚o bluzgi!" foul2 = "[:nick] klnie jak szewc (albo i gorzej) przez [:per]% czasu." foul3 = "Nikt nie klnie na [:channel]! Sami spokojni ludzie." foultext = "Na przykÅ‚ad coÅ› takiego:
     [:line]" smiles1 = "[:nick] usmiechaÅ‚[::a:] siÄ™ gÅ‚upawo albo byÅ‚[::a:] bardzo szczęśliw[:y:a:], bo [:per]% linii zawieraÅ‚o uÅ›miechniÄ™te miny :)" smiles2 = "[:nick] najwyraźniej miaÅ‚[::a:] powody do radoÅ›ci Å›miejÄ…c siÄ™ przez [:per]% czasu spÄ™dzonego na kanale." smiles3 = "Nikt siÄ™ nie uÅ›miechaÅ‚ na [:channel]! ProszÄ™ o uÅ›miech Panie i Panowie." sad1 = "[:nick] wyglÄ…da na smutnÄ… osobÄ™, [:per]% linii zawieraÅ‚o smutne miny :(" sad2 = "[:nick] nie czuje siÄ™ najlepiej na kanale smucÄ…c siÄ™ przez [:per]% czasu." sad3 = "Nikt nie jest smutny na [:channel]! Cóż za szczęśliwy kanaÅ‚ :)" month = "stycznia lutego marca kwietnia maja czerwca lipca sierpnia wrzeÅ›nia października listopada grudnia" day = "niedzielÄ™, poniedziaÅ‚ek, wtorek, Å›rodÄ™, czwartek, piÄ…tek, sobotÄ™," ## Topics bignumtopic = "Wielkie liczby" othernumtopic = "Inne interesujÄ…ce liczby" latesttopic = "Ostatnie tematy" activetimestopic = "Najaktywniejsze pory dnia" activenickstopic = "Najaktywniejsze nicki" activenickbyhourtopic = "Najaktywniejsze nicki w przedziaÅ‚ach godzin" mostwordstopic = "Najczęściej używane sÅ‚owa" referencetopic = "Najczęściej wywoÅ‚ywany nick" urlstopic = "Najczęściej wywoÅ‚ywany URL" notopic = "Å»aden temat nie zostaÅ‚ ustawiony na kanale." mostnickstopic = "Ircownicy z najwiÄ™ksza iloÅ›ciÄ… nicków" bylinetopic = "ustawiony [:date] przez [:nick] o [:time]" dailyactivitytopic = "Dzienna aktywność (ostatnie [:n] dni)" activegenderstopic = "Najbardziej aktywna pÅ‚eć" smileytopic = "UÅ›mieszki :-)" chartstopic = "Lista przebojów kanaÅ‚u [:channel]" karmatopic = "Karma kanaÅ‚u [:channel]" ## Other text totallines = "CaÅ‚kowita liczba linii: [:lines]" totalnicks = "ByÅ‚o również [:totalnicks] innych nicków." totaltopic = "Temat byÅ‚ ustawiany [:total] razy." nick = "Nick" names = "Użyte Nicki" url = "URL" numberlines = "Liczba linii" randquote = "Losowy cytat" userpic = "Fotka" nottop = "Oni nie dostali siÄ™ do czołówki:" word = "Wyraz" numberuses = "Liczba użyć" show_words = "Liczba słów" show_time = "W jakich porach" show_wpl = "Słów na liniÄ™" show_cpl = "Znaków na liniÄ™" show_lastseen = "Ostatnio widziany" lastused = "Ostatnio używany przez" lastseen1 = "[:days] dzieÅ„ temu" lastseen2 = "[:days] dni temu" today = "Dzisiaj" pagetitle1 = "Statystyki kanaÅ‚u [:channel] @ [:network] by [:maintainer]" pagetitle2 = "Statystyka wygenerowana w " pagetitle3 = "W przedziale [:days] dni łącznie [:nicks] nicków odwiedziÅ‚o kanaÅ‚ [:channel]." stats_gen_by = "Statystyki wygenerowane przez [:pisg_url] v[:version]" author = "pisg by [:author_url] i inni" stats_gen_in = "Statystyki wygenerowane w [:time]" hours = "godziny" minutes = "minuty" seconds = "sekundy" and = "i" names1 = "nicków" names2 = "nick" karma = "Karma" badkarma = "Nie lubiÄ… go/jej" goodkarma = "WdziÄ™czni za coÅ› byli jej/mu" smiley = "UÅ›mieszek" gender_f = "Kobieta" gender_m = "Mężczyzna" gender = "PÅ‚eć" gender_b = "Bot" song = "Utwór" playedby = "Ostatnio sÅ‚uchany przez" numberplayed = "Ile razy odtwarzany" # Mouse-over titles pisghomepage = "Odwiedź stronÄ™ domowÄ… programu pisg" authorhomepage = "Odwiedź stronÄ™ domowÄ… autora" newwindow = "Otwórz w nowym oknie:" mailto = "WyÅ›lij maila do:"
### Portuguese mostop1 = "[:nick] deu [:ops] ops no canal..." mostop2 = "[:nick] também foi [:simpático:simpática:]: [:ops] ops [:dele:dela:]." mostop3 = "Estranho, nenhum op foi dado no [:channel]!" mostdeop1 = "[:nick] é [:o:a:] policia do canal com [:deops] ops retirados." mostdeop2 = "[:nick] retirou o op a [:deops] utilizadores." mostdeop3 = "Ena, ninguém tirou ops no [:channel]!" mostvoice1 = "[:nick] doou [:voices] voices no canal..." mostvoice2 = "[:nick] também foi [:simpático:simpática:]: [:voices] voices [:dele:dela:]." mostvoice3 = "Estranho, não foram entregues voices no [:channel]!" mostdevoice1 = "[:nick] gosta de tirar voices às pessoas, [:devoices] voices retirados." mostdevoice2 = "[:nick] também não andou longe, retirou [:devoices] voices." mostdevoice3 = "Não houve voices retirados no [:channel]!" mosthalfop1 = "[:nick] doou [:halfops] halfops no canal..." mosthalfop2 = "[:nick] was also very polite: [:halfops] halfops from [:him:her:]." mosthalfop3 = "Strange, no halfop was given on [:channel]!" mostdehalfop1 = "[:nick] is the channel sheriff with [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] dehalfoped [:dehalfops] users." mostdehalfop3 = "Wow, no halfop was taken on [:channel]!" action1 = "[:nick] gosta de nos manter informados sobre o que está a fazer: [:actions] acções!" action2 = "Também [:o:a:] [:nick] nos diz o que anda a tramar com [:actions] acções." action3 = "Não houve acções no [:channel]!" actiontext = "Por exemplo:
     [:line]" question1 = "[:nick] é muito [:curioso:curiosa:]: [:per]% das suas linhas contém uma pergunta!" question2 = "Também [:o:a:] [:nick] não anda longe: [:per]% das suas linhas foram interrogativas." question3 = "Ninguém perguntou nada. Ninguém quer saber de nada?" shout1 = "[:O:A:] mais estridente foi [:o:a:] [:nick], que gritou [:per]% do tempo!" shout2 = "Outra corneta foi [:o:a:] [:nick], que berrou [:per]% do tempo!" shout3 = "Ninguém grita no canal, ena!" allcaps1 = "Parece que a tecla shift [:do:da:] [:nick] está presa: Em [:per]% do tempo escreveu em MAIÚSCULAS!" allcaps2 = "[:nick] esqueceu-se de desligar o caps-lock. [:Ele:Ela:] escreveu em MAIÚSCULAS [:per]% do tempo." allcaps3 = "Toda a gente manteve as suas teclas shift sob controlo. :)" allcapstext = "Por exemplo:
     [:line]" violent1 = "[:nick] é uma pessoa muito agressiva. [:Ele:Ela:] atacou outros [:attacks] vezes!" violent2 = "[:nick] também não controla a sua agressão. [:Ele:Ela:] pegou-se com outra pessoa [:attacks] vezes." violent3 = "Ninguém agrediu ninguém no canal. Todos são amigos." violenttext = "Por exemplo:
     [:line]" attacked1 = "Pobre [:nick], ninguém gosta [:dele:dela:]. Foi [:atacado:atacada:] [:attacks] vezes." attacked2 = "[:nick] também parece ser [:odiado:odiada:]. Recebeu [:attacks] ataques." attackedtext = "Por exemplo:
     [:line]" gotkick1 = "[:nick] não é lá muito popular, sendo [:kickado:kickada:] [:kicks] vezes!" gotkick2 = "[:nick] também não recebe muita estima: [:kicks] kicks recebidos." kicktext = "Por exemplo:
     [:line]" joins = "[:nick] não sabe se fica ou se sai. [:joins] joins relatados!" kick1 = "[:nick] ou é [:doido:doida:] ou é [:um:uma:] excelente op, kickando um total de [:kicked] utilizadores!" kick2 = "[:nick] parece ser aprendiz de [:oldnick], distribuindo [:kicked] kicks." kick3 = "Os ops são simpáticos neste canal, ninguém foi kickado!" words1 = "[:nick] teclou um total de [:words] palavras!" words2 = "[:nick] não teclou tanto: [:words] palavras." words3 = "Ninguém diz nada? Que raio de canal..." mono1 = "[:nick] fala muito [:sózinho:sózinha:]. Mais de 5 linhas seguidas [:monos] vezes!" mono2 = "[:Outro:Outra:] [:solitário:solitária:], [:nick], que conseguiu chegar às [:monos] vezes." wpl1 = "[:nick] escreveu uma média de [:wpl] palavras por linha." wpl2 = "A média do canal é de [:avg] palavras por linha." long1 = "[:nick] escreveu as linhas mais compridas, [:letters] letras por linha." long2 = "A média do [:channel] é de [:avg] letras por linha." short1 = "[:nick] escreveu as linhas mais curtas, com uma média de [:letters] letras por linha." short2 = "[:nick] também tecla pouco, com uma média de [:letters] letras." foul1 = "[:nick] tem uma boca suja. [:per]% das suas palavras eram palavrões." foul2 = "[:nick] também faz corar um pedreiro, praguejando [:per]% do tempo." foul3 = "Ninguém diz asneiras no [:channel]! Incrível!" foultext = "Por exemplo:
     [:line]" smiles1 = "[:nick] é muito feliz. [:per]% das linhas contém caras sorridentes. :)" smiles2 = "[:nick] também não é nada triste, sorrindo [:per]% do tempo." smiles3 = "Ninguém sorri no [:channel]! Animem-se!" sad1 = "[:nick] parece estar triste: [:per]% contém caras tristes. :(" sad2 = "[:nick] também não anda longe, chorando [:per]% do tempo." sad3 = "Ninguém chora no [:channel]! Que canal alegre! :)" month = "Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro" day = "Domingo Segunda Terça Quarta Quinta Sexta Sabado" ## Topics bignumtopic = "Alguns números" othernumtopic = "Outros números interessantes" latesttopic = "Tópicos recentes" activetimestopic = "Horas mais activas" activenickstopic = "Nicks mais activos" activenickbyhourtopic = "Nicks mais activos por horas" mostwordstopic = "Palavras mais usadas" referencetopic = "Nicks mais referênciados" smileytopic = "Caras :-)" karmatopic = "[:channel] disposição" urlstopic = "URLs mais referênciados" notopic = "Nenhum tópico foi colocado neste canal." mostnickstopic = "Utilizadores com mais nicks" bylinetopic = "[:date] por [:nick] às [:time]" dailyactivitytopic = "Actividade diária (últimos [:n] dias)" activegenderstopic = "Sexo mais activo" chartstopic = "[:channel] Exitos musicales" ## Other text totallines = "Número total de linhas: [:lines]." totalnicks = "Ainda houve mais [:totalnicks] nicks." totaltopic = "O tópico foi modificado [:total] vezes." nick = "Nick" names = "Nomes usados" url = "URL" numberlines = "Número de linhas" randquote = "Citação aleatória" userpic = "Foto do utilizador" nottop = "Estes não chegaram ao topo:" word = "Palavra" numberuses = "Número de Utilizações" show_words = "Número de Palavras" show_time = "Quando?" show_wpl = "Palavras por linha" show_cpl = "Letras por linha" show_lastseen = "Visto pela última vez" lastused = "Utilizado pela última vez por" smiley = "Caras" karma = "Disposição" goodkarma = "Boa disposição por" badkarma = "Má disposição por" lastseen1 = "[:days] dia atrás" lastseen2 = "[:days] dias atrás" today = "Hoje" pagetitle1 = "[:channel] @ [:network] estatisticas por [:maintainer]" pagetitle2 = "Estatisticas geradas " pagetitle3 = "Durante este periodo de [:days] dias, um total de [:nicks] nicks diferentes foram vistos no [:channel]." stats_gen_by = "Estatísticas geradas pelo [:pisg_url] v[:version]" author = "pisg por [:author_url] e outros" stats_gen_in = "Estatisticas geradas em [:time]" hours = "horas" minutes = "minutos" seconds = "segundos" and = "e" names1 = "nomes" names2 = "nome" gender = "Sexo" gender_f = "Feminino" gender_m = "Masculino" gender_b = "Bot" song = "Canção" numberplayed = "Tocada quantas vezes" playedby = "Tocada pela ultima vez por" # Mouse-over titles pisghomepage = "Ir para a página do pisg" authorhomepage = "Ir para a página do autor" newwindow = "Abrir uma nova janela:" mailto = "Enviar mail para"
### Flemish mostop1 = "[:nick] gaf [:ops] @'s in deze chatbox..." mostop2 = "[:nick] was ook vriendelijk. [:ops] werden er uitgedeeld door [:hem:haar:]." mostop3 = "Wat raar, geen @'s gegeven op [:channel]!" mostdeop1 = "[:nick] dacht dat [:hij:zij:] het kanaal wel alleen in bedwang kon houden en deopte [:deops] personen..." mostdeop2 = "[:nick] deopte [:deops] chatters." mostdeop3 = "Wow, geen ops afgepakt in [:channel]!" mostvoice1 = "[:nick] gaf [:voices] voicekes in het kanaal..." mostvoice2 = "[:nick] was ook erg beleefd: [:voices] voicekes van [:hem:haar:]." mostvoice3 = "Raar, geen voicekes gegeven op [:channel]!" mostdevoice1 = "[:nick] neemt graag voickes af van mensen, [:hij:zij:] devoicede [:devoices] mensen." mostdevoice2 = "[:nick] neemt ook graag voickes af, [:hij:zij:] devoicede [:devoices] mensen." mostdevoice3 = "Er waren geen voicekes afgenomen op [:channel]!" mosthalfop1 = "[:nick] gaf [:halfops] keer halfop status in het kanaal..." mosthalfop2 = "[:nick] was ook beleefd; [:hij:zij:] gaf [:halfops] keer halfop status." mosthalfop3 = "Raar, er zijn geen halfops gegeven in [:channel]!" mostdehalfop1 = "[:nick] houde orde met [:dehalfops] keer halfop status af te nemen." mostdehalfop2 = "[:nick] wou ook de orde behouden en heeft [:dehalfops] keer halfop status afgenomen." mostdehalfop3 = "Amai, er is geen halfop status afgenomen op [:channel]!" question1 = "[:nick] is gewoon stom of verzint de vragen waar je bijstaat... [:per]% bevatte een vraag!" question2 = "[:nick] is bijna net zo stom/blond, [:per]% van [:zijn:haar:] regels eindigde ook met een "?"." question3 = "Niemand vroeg wat hier, ze denken zeker allemaal dat ze slim zijn .... NOT?" action1 = "[:nick] laat ook weten wat [:hij:zij:] doet: met [:actions] actie's!" action2 = "Ook [:nick] vertelt ons wat [:hij:zij:] doet met [:actions] actie's." action3 = "Er was niet zoveel actie in [:channel]!" actiontext = "Bijvoorbeeld zoals dit:
     [:line]" shout1 = "De grootste lawaaimaker was [:nick], [:hij:zij:] schreeuwde [:per]% tijdens [:zijn:haar:] aanwezigheid!" shout2 = "Ook had [:nick] een groot bakkes, [:hij:zij:] schreeuwde [:per]% tijdens [:zijn:haar:] aanwezigheid." shout3 = "Hmm niet veel geschreeuw hier, wat een zelfbeheersing :)." allcaps1 = "Het lijkt dat [:nick]'s [:zijn:haar:] shift-key kapot is, met een CAPS-percentage van [:per]%." allcaps2 = "Ook [:nick] is het niet gelukt om [:zijn:haar:] Caps-Lock onder controle te krijgen, [:per]% CAPS." allcaps3 = "Iedereen had het hoofdletter gebruik onder de knie :)." allcapstext = "Bijvoorbeeld zoals dit:
     [:line]" violent1 = "[:nick] is een agressief persoon, die veel in het rond slaat. Deze keer wel [:attacks] keer." violent2 = "[:nick] [:zijn:haar:] pilletjes helpen niet. [:Hij:Zij:] sloeg [:attacks] keer." violent3 = "Geen slaps uitgedeeld hier, wat vriendelijke mense hier. :p" violenttext = "Bijvoorbeeld zoals dit:
     [:line]" attacked1 = "Zielige [:nick], niemand mag [:hem:haar:]. [:Hij:Zij:] werd [:attacks] keer aangevallen." attacked2 = "[:nick] is nog zo'n ongewenst zieltje, [:hij:zij:] werd [:attacks] keer gepijnigd." attackedtext = "Bijvoorbeeld zoals dit:
     [:line]" gotkick1 = "[:nick] was gewoon niet populair genoeg, en werd [:kicks] keer gekickt!" gotkick2 = "[:nick] werd ook niet echt gewaardeerd, met [:kicks] kicks." kicktext = "Bijvoorbeeld zoals dit:
     [:line]" joins = "[:nick] wist niet of [:hij:zij:] nu moest komen of gaan en kwam [:joins] keer binnen in deze periode!" kick1 = "De wrede tiran van het kanaal is [:nick]. [:Hij:Zij:] kickte een totaal van [:kicked] chatters!" kick2 = "[:oldnick]'s wannabe , [:nick], Wou ook cool overkomen en kickte er [:kicked]." kick3 = "Vriendelijke Ops hier, totaal geen kicks!" words1 = "[:nick] sprak [:words] woorden in totaal!" words2 = "[:oldnick]'s wannabe, [:nick], sprak gelukkig iets minder, maar toch nog [:words] woorden." words3 = "Is het niet de bedoeling dat men spreekt in [:channel] of ben ik verkeerd?" mono1 = "[:nick] praat veel in zichzelf. [:Hij:Zij:] schreef meer dan 5 lijnen achter elkaar en deed dit [:monos] keer!" mono2 = "Nog zo'n simpel, eenzaam zieltje was [:nick], die het voor elkaar kreeg om meer dan 5 lijnen achter elkaar te schrijve voor [:monos] keer!" wpl1 = "[:nick] schreef een gemiddelde van [:wpl] woorden per regel..." wpl2 = "[:channel] gemiddelde was [:avg] woorden per regel." long1 = "[:nick] schreef de langste regels, gemiddelde van [:letters] letters per regel..." long2 = "[:channel] gemiddelde was [:avg] letters per regel." short1 = "[:nick] schreef de kortste regels, gemiddelde van maar [:letters] letters per regel..." short2 = "[:nick] had ook niet veel inspiratie, gemiddeld maar [:letters] letters per regel." foul1 = "[:nick] kon het maar niet laten te vloeken, [:per]% van de regels bevatte *exotische termen*." foul2 = "[:nick] kan er ook wat van, en scheld [:per]% van de tijd." foul3 = "Iedereen is vriendelijk in [:channel]! Leven ze zich teveel uit op hun werk ofzow?" foultext = "Een voorbeeld:
     [:line]" smiles1 = "[:nick] maakt de wereld weer vrolijk , [:per]% van de regels bevatte een smiley :o)" smiles2 = "[:nick] heeft het ook wel naar [:zijn:haar:] zin, en lachte [:per]% van de tijd." smiles3 = "Niemand lachte op [:channel]! Bende citroenen :p." sad1 = "[:nick] is niet echt vrolijk , [:per]% van de regels bevatte een sad face :(" sad2 = "[:nick] is ook al niet te vrolijk met een sad percentage van [:per]%." sad3 = "Niemand is "Bedroefd" op [:channel]! What a happy channel :-)." ## Topics bignumtopic = "Grote Getallen" othernumtopic = "Andere interessante getallen" latesttopic = "Laatste topics" activenickbyhourtopic = "Meest actieve personen per uur" activetimestopic = "Meest actieve tijden" activenickstopic = "Meest actieve nicks" mostwordstopic = "Meest genoemde woorden" referencetopic = "Meest genoemde nicks" karmatopic = "[:channel] karma" urlstopic = "Meest genoemde URLs" notopic = "De mensen hier weten nog steeds niet hoe ze +t moeten gebruiken." bylinetopic = "[:date] door [:nick] op [:time]" dailyactivitytopic = "Dagelijkse activiteit (afgelopen [:n] dagen)" mostnickstopic = "Gebruiker met de meeste nicks" activegenderstopic = "Meest actieve geslacht" smileytopic = "Smileys :-)" chartstopic = "[:channel] Muziek Hitlijsten" ## Other text totallines = "Totaal aantal regels: [:lines]" totalnicks = "Oja, er waren ook nog [:totalnicks] andere nicks." totaltopic = "De topic is [:total] maal veranderd." nick = "Nick" url = "URL" numberlines = "Aantal regels" randquote = "Willekeurig citaat" userpic = "Foto" nottop = "Deze behoorden gewoon niet tot "The Elite":" word = "Woord" numberuses = "Aantal keren genoemd" lastused = "Laatst genoemd door" karma = "Karma" goodkarma = "Goed karma door" badkarma = "Slecht karma door" pagetitle1 = "[:channel] @ [:network] statistieken door [:maintainer]" pagetitle2 = "Statistieken gegenereerd op " pagetitle3 = "Tijdens deze [:days]-daagse periode waren er in totaal [:nicks] verschillende nicks te vinden op [:channel]." show_words = "Aantal woorden" show_time = "Wanneer?" show_wpl = "Woorden per regel" show_cpl = "Karakters per regel" show_lastseen = "Laatst gezien" lastseen1 = "[:days] dag geleden" lastseen2 = "[:days] dagen geleden" today = "Vandaag" month = "Januari Februari Maart April Mei Juni Juli Augustus September Oktober November December" day = "zondag maandag dinsdag woensdag donderdag vrijdag zaterdag" stats_gen_by = "Stats gegenereerd door [:pisg_url] v[:version]" author = "pisg wordt gemaakt door [:author_url] en anderen" stats_gen_in = "Stats gegenereerd in [:time]" hours = "uren" minutes = "minuten" seconds = "seconden" and = "en" names = "Gebruikte nicks" names1 = "Nicks" names2 = "Nick" gender = "Geslacht" gender_f = "Vrouwelijk" gender_m = "Mannelijk" gender_b = "Bot" smiley = "Smiley" song = "Nummer" numberplayed = "Hoe Vaak Gedraaid" playedby = "Laatst Gedraaid door" # Mouse-over titles pisghomepage = "Ga naar de pisg homepage" authorhomepage = "Ga naar de homepage van de auteur" newwindow = "Open in nieuw scherm:" mailto = "Mail naar"
### Dutch (Nederlands) mostop1 = "[:nick] gaf [:ops] ops in het kanaal..." mostop2 = "[:nick] was ook erg beleefd: [:ops] ops van [:hem:haar:]." mostop3 = "Vreemd, er werd geen op gegeven in [:channel]!" mostdeop1 = "[:nick] is de kanaalagent met [:deops] deops." mostdeop2 = "[:nick] deopte [:deops] gebruikers." mostdeop3 = "Wow, er werd geen op afgepakt in [:channel]!" mostvoice1 = "[:nick] gaf [:voices] voices in het kanaal..." mostvoice2 = "[:nick] was ook erg beleefd: [:voices] voices van [:hem:haar:]." mostvoice3 = "Vreemd, er werden geen voices gegeven in [:channel]!" mostdevoice1 = "[:nick] houdt ervan om mensen de voice af te pakken, [:devoices] devoices." mostdevoice2 = "[:nick] zat er dicht bij, devoicede [:devoices] gebruikers." mostdevoice3 = "Er werden geen voices afgepakt in [:channel]!" mosthalfop1 = "[:nick] gaf [:halfops] halfops in het kanaal..." mosthalfop2 = "[:nick] was ook erg vriendelijk: [:halfops] halfops van [:hem:haar:]." mosthalfop3 = "Vreemd, er werd geen halfop gegeven in [:channel]!" mostdehalfop1 = "[:nick] is de kanaalagent met [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] dehalfopte [:dehalfops] gebruikers." mostdehalfop3 = "Wow, er werd geen halfop afgepakt in [:channel]!" action1 = "[:nick] laat ons altijd weten wat [:hij:zij:] aan het doen is: [:actions] acties!" action2 = "Ook, [:nick] verteld ons wat er aan de hand is met [:actions] acties." action3 = "Geen acties in [:channel]!" actiontext = "Zoals dit bijvoorbeeld:
     [:line]" question1 = "Is [:nick] stom of stelt [:hij:zij:] gewoon te veel vragen? [:per]% regels bevatten een vraag!" question2 = "[:nick] wist ook al niet zoveel. [:per]% van [:zijn:haar:] regels waren vragen." question3 = "Niemand stelde hier vragen; alleen maar genieën in dit kanaal?" shout1 = "De luidste was [:nick], die schreeuwde [:per]% van de tijd!" shout2 = "Een andere beruchte schreeuwer was [:nick], die schreeuwde [:per]% van de tijd!" shout3 = "Er schreeuwde helemaal niemand, wow." allcaps1 = "Het schijnt dat [:nick]'s shift-toets blijft hangen: [:per]% van de tijd schreef [:hij:zij:] IN HOOFDLETTERS." allcaps2 = "[:nick] vergat gewoon [:zijn:haar:] Caps-Lock uit te zetten. [:Hij:Zij:] schreef IN HOOFDLETTERS [:per]% van de tijd." allcaps3 = "Iedereen had hun shift-toets onder controle. :)" allcapstext = "Zoals dit bijvoorbeeld:
     [:line]" violent1 = "[:nick] is een zeer agressief persoon. [:Hij:Zij:] viel andere [:attacks] keer aan." violent2 = "[:nick] kan ook [:zijn:haar:] agressie niet onder controle houden. [:Hij:Zij:] pestte andere [:attacks] keer." violent3 = "Niemand sloeg iemand in elkaar. Iedereen was vriendelijk." violenttext = "Zoals dit bijvoorbeeld:
     [:line]" attacked1 = "Arme [:nick], niemand mag [:hem:haar:]. [:Hij:Zij:] werd [:attacks] keer aangevallen." attacked2 = "[:nick] schijnt ook niet aardig gevonden te worden. [:Hij:Zij:] kreeg [:attacks] keer een pak slaag." attackedtext = "Zoals dit bijvoorbeeld:
     [:line]" gotkick1 = "[:nick] was niet erg populair, werd [:kicks] keer geschopt!" gotkick2 = "[:nick] Schijnt ook gehaat te worden: [:kicks] schoppen ontvangen." kicktext = "Zoals dit bijvoorbeeld:
     [:line]" joins = "[:nick] kon maar niet beslissen om te blijven of om te gaan. [:joins] entrees tijdens deze rapportageperiode!" kick1 = "[:nick] is of krankzinnig of gewoon een eerlijke op, schopte een totaal van [:kicked] mensen!" kick2 = "[:oldnick]'s trouwe volger, [:nick], schopte ongeveer [:kicked] mensen." kick3 = "Vriendelijke opers hier, niemand werd geschopt!" words1 = "[:nick] sprak in totaal [:words] woorden!" words2 = "[:oldnick]'s trouwe volger, [:nick], sprak niet zo veel: [:words] woorden." words3 = "Niemand zei er wat... Wat een vreemd kanaal..." mono1 = "[:nick] praat veel met [:zich:haar:]zelf. [:Hij:Zij:] schreef meer dan 5 regels achter elkaar en dat [:monos] keer!" mono2 = "Een andere eenzame was [:nick], die er [:monos] keer in slaagde." wpl1 = "[:nick] schreef gemiddeld [:wpl] woorden per regel." wpl2 = "Kanaal gemiddelde was [:avg] woorden per regel." long1 = "[:nick] schreef de langste regels, gemiddeld [:letters] letters per regel." long2 = "[:channel] gemiddelde was [:avg] letters per regel." short1 = "[:nick] schreef de kortste regels, gemiddeld [:letters] karakters per regel." short2 = "[:nick] hield ook de lippen op elkaar, gemiddeld [:letters] karakters." foul1 = "[:nick] heeft een behoorlijke brutale mond. [:per]% van de woorden waren ongepast." foul2 = "[:nick] laat zelfs zeelieden blozen, [:per]% van de tijd." foul3 = "Niemand heeft een grote mond in [:channel]! Komt men wel eens buiten?" foultext = "Zoals dit bijvoorbeeld:
     [:line]" smiles1 = "[:nick] brengt geluk in de wereld. [:per]% regels bevatte lachende gezichten. :)" smiles2 = "[:nick] is ook geen somber persoon, lachte [:per]% van de tijd." smiles3 = "Niemand lacht in [:channel]! Kop op jongens en meiden." sad1 = "[:nick] schijnt op het ogenblik somber te zijn: [:per]% regels bevatte sombere gezichten. :(" sad2 = "[:nick] is ook een somber persoon, huilde [:per]% van de tijd." sad3 = "Niemand is somber in [:channel]! Wat een gelukkig kanaal. :-)" month = "Januari Februari Maart April Mei Juni Juli Augustus September Oktober November December" day = "Zondag Maandag Dinsdag Woensdag Donderdag Vrijdag Zaterdag" ## Topics bignumtopic = "Grote getallen" othernumtopic = "Andere interessante getallen" latesttopic = "Laatste onderwerpen" activetimestopic = "Meest actieve tijden" activenickstopic = "Meest actieve nicks" activenickbyhourtopic = "Meest actieve personen per uur" mostwordstopic = "Meest gebruikte woorden" referencetopic = "Meest genoemde nicks" karmatopic = "[:channel] karma" urlstopic = "Meest genoemde URLs" notopic = "Er is in dit kanaal nooit een onderwerp vastgesteld." mostnickstopic = "Gebruiker met de meeste nicks" bylinetopic = "[:date] om [:time] door [:nick] " dailyactivitytopic = "Dagelijkse activiteit (afgelopen [:n] dagen)" activegenderstopic = "Meest actieve geslacht" smileytopic = "Smileys :-)" chartstopic = "[:channel] Muziek Hitlijsten" ## Other text totallines = "Totaal aantal regels: [:lines]" totalnicks = "Trouwens, er waren ook nog [:totalnicks] andere nicks." totaltopic = "Het onderwerp is [:total] keer veranderd." nick = "Nick" names = "Gebruikte namen" url = "URL" numberlines = "Aantal regels" randquote = "Willekeurig citaat" userpic = "Gebruikersfoto" nottop = "Deze haalden de top niet:" word = "Woord" numberuses = "Aantal keren gebruikt" show_words = "Aantal woorden" show_time = "Wanneer?" show_wpl = "Woorden per regel" show_cpl = "Karakters per regel" show_lastseen = "Laatst gezien" lastused = "Laatst gebruikt door" karma = "Karma" goodkarma = "Goed karma door" badkarma = "Slecht karma door" lastseen1 = "gisteren" lastseen2 = "[:days] dagen geleden" today = "vandaag" pagetitle1 = "[:channel] @ [:network] statistieken door [:maintainer]" pagetitle2 = "Statistieken gegenereerd op " pagetitle3 = "Tijdens deze [:days]-daagse rapporterings periode waren er in totaal [:nicks] verschillende nicks te vinden op [:channel]." stats_gen_by = "Stats gegenereerd door [:pisg_url] v[:version]" author = "pisg door [:author_url] en anderen" stats_gen_in = "Stats gegenereerd in [:time]" hours = "uren" minutes = "minuten" seconds = "seconden" and = "en" names1 = "namen" names2 = "naam" gender = "Geslacht" gender_f = "Vrouwelijk" gender_m = "Mannelijk" gender_b = "Bot" smiley = "Smiley" song = "Nummer" numberplayed = "Hoe Vaak Gedraaid" playedby = "Laatst Gedraaid door" # Mouse-over titles pisghomepage = "Ga naar de pisg homepage" authorhomepage = "Ga naar de homepage van de auteur" newwindow = "Openen in nieuw scherm:" mailto = "Mail naar"
### Swedish mostop1 = "[:nick] gav [:ops] personer operatörsstatus i kanalen..." mostop2 = "[:nick] var också väldigt vänlig: [:ops] från [:honom:henne:]" mostop3 = "Underligt, inga personer fick operatörsstatus i [:channel]!" mostdeop1 = "[:nick] var kanalens sheriff och tog ifrån [:deops] personer deras operatörsstatus..." mostdeop2 = "[:nick] tog ifrån [:deops] användare sin operatörsstatus" mostdeop3 = "Wow, inga personer blev av med sin operatörsstatus i [:channel]!" mostvoice1 = "[:nick] gav [:voices] voicestatus i kanalen..." mostvoice2 = "[:nick] var och väldigt snäll: [:voices] voicestatus från [:honom:henne:]" mostvoice3 = "Konstigt, inga voicestatus gavs i [:channel]!" mostdevoice1 = "[:nick] gillar att ta voicestatus från folk, [:devoices] st." mostdevoice2 = "[:nick] var inte heller snäll, tog bort voicestatus från [:devoices] användare." mostdevoice3 = "Ingen blev av med sin voicestatus i [:channel]!" mosthalfop1 = "[:nick] gav [:halfops] halvoperatörsstatus i kanalen..." mosthalfop2 = "[:nick] var också väldigt snäll: [:halfops] halvoperatörsstatus från [:honom:henne:]." mosthalfop3 = "Konstigt, inga halvoperatörer i [:channel]!" mostdehalfop1 = "[:nick] är kanalens sheriff och tog ifrån [:dehalfops] deras halvoperatörsstatus." mostdehalfop2 = "[:nick] tog ifrån [:dehalfops] användare deras halvoperatörsstatus." mostdehalfop3 = "Wow, inga förlorade sin halvoperatörsstatus i [:channel]!" action1 = "[:nick] berättar alltid för oss vad [:han:hon:] gör: [:actions] beskrivningar!" action2 = "även [:nick] berättar vad som händer med [:actions] beskrivningar." action3 = "Inga beskrivningar i [:channel]!" actiontext = "Till exempel, såhär:
     [:line]" question1 = "[:nick] är antingen dum eller ställer bara många frågor... [:per]% rader innehöll en fråga!" question2 = "[:nick] visste inte heller mycket, [:per]% av [:hans:hennes:] rader innehöll en fråga" question3 = "Ingen frågade någonting, bara genier i denna kanalen?" shout1 = "Skrikigast var [:nick] som skrek [:per]% av tiden!" shout2 = "En annan skrikhals var [:nick] som skrek [:per]% av tiden!" shout3 = "Ingen använde utropstecknet, wow." allcaps1 = "Det verkar som [:nick] har en hängande shift-tangent, [:per]% av tiden skrev [:han:hon:] i VERSALER" allcaps2 = "[:nick] glömde att deaktivera sin CapsLock-tangent, [:per]% av det [:han:hon:] skrev var VERSALER" allcaps3 = "Alla hade sin shift-tangent under kontroll :)" allcapstext = "Till exempel såhär:
     [:line]" violent1 = "[:nick] är en väldigt aggressiv person och använde handflatan [:attacks] gånger." violent2 = "[:nick] kunde inte kontrollera sina aggressioner. [:Han:Hon:] slogs [:attacks] gånger med sin handflata." violent3 = "Ingen slog någon, alla var vänner." violenttext = "Till exempel såhär:
     [:line]" attacked1 = "Stackars [:nick], ingen gillade [:honom:henne:]. [:Han:Hon:] blev slagen [:attacks] gånger med handflatan." attacked2 = "[:nick] var inte heller speciellt omtyckt, [:han:hon:] blev slagen [:attacks] gånger." attackedtext = "Till exempel såhär:
     [:line]" gotkick1 = "[:nick] var inte speciellt populär och blev utsparkad [:kicks] gånger!" gotkick2 = "[:nick] verkar också vara hatad, [:kicks] utsparkningar" kicktext = "Till exempel såhär:
     [:line]" joins = "[:nick] kunde inte bestämma sig för att stanna eller gå och gjorde entré [:joins] gånger under den rapporterade perioden!" kick1 = "[:nick] är galen eller bara en rättvis operatör, sparkade ut totalt [:kicked] personer!" kick2 = "[:oldnick] har en efterföljare: [:nick], som sparkade ut [:kicked] personer" kick3 = "Trevliga operatörer här, ingen blev utsparkad!" words1 = "[:nick] är mycket aktiv och skrev totalt [:words] ord!" words2 = "Pratkvarnen [:oldnick] blev tätt följd av [:nick], som inte pratade riktigt lika mycket: [:words] ord." words3 = "Ingen sa något... Vilken konstig kanal..." mono1 = "[:nick] pratar mycket med sig själv och skrev över 5 rader i följd [:monos] gånger!" mono2 = "En annan ensam person var [:nick], som lyckades med [:monos] monologer" wpl1 = "[:nick] skrev ett genomsnitt av [:wpl] ord per rad..." wpl2 = "Kanalens genomsnitt var [:avg] ord per rad." long1 = "[:nick] skrev längst rader, genomsnittet var [:letters] tecken per rad..." long2 = "Kanalgenomsnittet i [:channel] var [:avg] tecken per rad" short1 = "[:nick] skrev kortast rader, med ett genomsnitt av [:letters] tecken per rad..." short2 = "[:nick] var också tystlåten, genomsnitt [:letters]" foul1 = "[:nick] borde tvätta munnen, [:per]% av raderna innehöll fula ord" foul2 = "[:nick] får också sjömännen att rodna, [:per]% av tiden svors det" foul3 = "Ingen svor i [:channel]! Ute mycket?" foultext = "Till exempel, såhär:
     [:line]" smiles1 = "[:nick] skänker lycka till världen, [:per]% av raderna innehöll glada miner :)" smiles2 = "[:nick] är inte heller en ledsen person, log [:per]% av tiden" smiles3 = "Ingen i [:channel] är glad! Upp med humöret nu pojkar och flickor." sad1 = "[:nick] verkar vara ledsen för tillfället, [:per]% av raderna innehöll sura miner :(" sad2 = "[:nick] är också en ledsen person, som grät [:per]% av tiden" sad3 = "Ingen i [:channel] är ledsen! Välkommen till den glada kanalen :-)" month = "Januari Februari Mars April Maj Juni Juli Augusti September Oktober November December" day = "Söndag Måndag Tisdag Onsdag Torsdag Fredag Lördag" ## Topics bignumtopic = "Stora nummer" othernumtopic = "Andra intressanta nummer" latesttopic = "Senaste rubrikerna" activetimestopic = "Mest aktiva tider" activenickstopic = "Mest aktiva personer" activenickbyhourtopic = "Mest aktiva personer per timme" mostwordstopic = "Mest använda ord" karmatopic = "Karma för [:channel]" referencetopic = "Mest tilltalade personer" smileytopic = "Smileys :-)" urlstopic = "Mest refererade URLer" notopic = "Ingen rubrik blev nånsin satt på denna kanal" chartstopic = "Hitlistan i [:channel]" bylinetopic = "[:date] av [:nick] klockan [:time]" dailyactivitytopic = "Daglig aktivitet (senaste [:n] dagarna)" activegenderstopic = "Mest aktiva kön" ## Other text totallines = "Totalt antal rader: [:lines]" totalnicks = "Och förresten, det var [:totalnicks] andra alias som inte kom med." totaltopic = "Kanalrubriken ändrades [:total] gånger." nick = "Namn/Alias" names1 = "namn" names2 = "namn" names = "Namn använda" url = "URL" numberlines = "Antal rader" randquote = "Slumpmässigt citat" userpic = "Användarbild" nottop = "Dessa personer kom inte med i toppen:" word = "Ord" numberuses = "Antal gånger" smiley = "Smiley" karma = "Karma" goodkarma = "Bra karma" badkarma = "Dålig karma" lastused = "Sist använt av" lastseen1 = "[:days] dag sen" lastseen2 = "[:days] dagar sen" pagetitle1 = "[:channel] @ [:network] statistik av [:maintainer]" pagetitle2 = "Statistik genererad " pagetitle3 = "Under denna [:days]-dagars rapporteringsperiod, blev ett totalt antal av [:nicks] olika personer representerade i [:channel]." stats_gen_by = "Stats genererade av [:pisg_url] v[:version]" author = "pisg skapat av [:author_url] med flera" stats_gen_in = "Statistiken tog [:time] att generera" today = "Idag" show_time = "När?" show_words = "Antal ord" show_lastseen = "Sågs senast" show_wpl = "Ord per rad" show_cpl = "Tecken per rad" hours = "timmar" minutes = "minuter" seconds = "sekunder" and = "och" mostnickstopic = "Användare med flest namn" gender = "Kön" gender_f = "Kvinna" gender_m = "Man" gender_b = "Bot" numberplayed = "Antal gånger spelad" song = "Låt" playedby = "Senast spelad av" # Mouse-over titles pisghomepage = "pisg's hemsida" authorhomepage = "Till utvecklarens hemsida" newwindow = "Öppna i nytt fönster:" mailto = "Email till"
### Finnish (Suomi) mostop1 = "[:nick] jakeli kanavalla oppeja [:ops] kertaa!" mostop2 = "[:nick] oli myös todella kohtelias: hän jakoi oppeja [:ops] kertaa." mostop3 = "Kumma kyllä, ketään ei opattu kanavalla [:channel]..." mostdeop1 = "[:nick] yritti olla pomo [:deops] deopilla..." mostdeop2 = "Sijaispomoksi pyrkii [:nick]: nöyryyttänyt muita [:deops] kertaa!" mostdeop3 = "Huh huh! [:channel] ei tällä kertaa rankaissut ketään!" mostvoice1 = "[:nick] antoi voiceja (+v) [:voices] henkilölle." mostvoice2 = "Myös [:nick] voicetti ahkerasti: [:voices] kertaa!" mostvoice3 = "Tällä kertaa [:channel]:n voicet on kiven alla..." mostdevoice1 = "[:nick] riisti irkkaajilta voiceja [:devoices] kertaa!" mostdevoice2 = "Perässä seuraa [:nick]: hän otti [:channel]:lla voiceja pois [:devoices] kertaa..." mostdevoice3 = "[:channel]:n voicetkin pysyivät irkkaajilla :)" mosthalfop1 = "[:nick] antoi puoliopit(+h) [:halfops] henkilölle!" mosthalfop2 = "Toiseksi eniten puolioppeja jakoi [:nick], kaikkiaan [:halfops] kertaa." mosthalfop3 = "Tällä kertaa [:channel]:lla ei tippunut puolioppeja kenellekään..." mostdehalfop1 = "[:nick] riisti irkkaajilta puolioppeja [:dehalfops] kertaa!" mostdehalfop2 = "Perässä seuraa [:nick]: hän otti puolioppeja pois [:dehalfops] kertaa..." mostdehalfop3 = "Keneltäkään ei riistetty puolioppeja [:channel]:lla :)" action1 = "[:nick] halusi kaikkien tietävän mitä on tekemässä: [:actions] /me:tä!" action2 = "Myöskin [:nick] osaa olla itserakas: selitteli tekemisiään [:actions] kertaa..." action3 = "Ei yhtään toimintaa [:channel]:lla!" actiontext = "Yksi esimerkki:
     [:line]" question1 = "Onko [:nick] vähän tyhmä vai muuten kyselee liikaa? [:per]% hänen kirjoittamista riveistään olivat kysymyksiä!" question2 = "[:nick] on myöskin vähän hölmö... [:per]% hänen puheistaan olivat kysymyksiä..." question3 = "Kukaan ei kysellyt mitään! Onko tämä kanava täynnä neroja?" shout1 = "Eniten meistä kirkui [:nick], tarkemmin ottaen [:per]% ajasta!" shout2 = "Toinen temperamenttikko oli [:nick], joka huusi [:per]% ajasta..." shout3 = "[:channel]:n käyttäjät ovat ilmeisen hissukoita, kukaan heistä ei huutanut kertaakaan!" allcaps1 = "Näyttää siltä että [:nick] on unohtanut Caps Lockin päälle: peräti [:per]% ajasta hän kirjoitti ISOILLA..." allcaps2 = "Kanavan toinen dementikko on [:nick]: Caps Lock päällä [:per]% ajasta!" allcaps3 = "Kumma kyllä, kukaan ei riehunut capseilla..." allcapstext = "Yksi esimerkki:
     [:line]" violent1 = "[:nick] on todella hyökkäävä persoona! Hän pahoinpiteli muita irkkaajia peräti [:attacks] kertaa!" violent2 = "[:nick] on myös agressiivinen. Hän pahoinpiteli muita [:attacks] kertaa..." violent3 = "Kukaan ei ole käyttäytynyt aggressiivisesti muita kohtaan, olemmeko saavuttaneet rauhan?" violenttext = "Yksi esimerkki:
     [:line]" attacked1 = "[:nick] parka, kukaan ei pidä hänestä. Häntä kohdeltiin kaltoin peräti [:attacks] kertaa!" attacked2 = "[:nick] näyttää olevan myös epäsuosiossa. Häntä pahoinpideltiin toiseksi eniten - [:attacks] kertaa..." attackedtext = "Yksi esimerkki:
     [:line]" gotkick1 = "[:nick] sai kenkää ennätykselliset [:kicks] kertaa!" gotkick2 = "[:nick] seuraa perässä: saanut kenkää [:kicks] kertaa..." kicktext = "Yksi esimerkki:
     [:line]" joins = "[:nick] Ei osaa päättää, että ollako vaiko eikö olla. Tarkastellun ajanjakson aikana hän on liittynyt kanavalle [:joins] kertaa!" kick1 = "[:nick] ei harrasta YT-neuvotteluja; hän antoi kenkää peräti [:kicked] käyttäjälle!" kick2 = "[:nick] koitti niinikään pomottaa [:kicked] potkuilla..." kick3 = "[:channel] on ilmeisen rauhallinen paikka, sillä ketään ei potkittu ulos tarkastellun ajanjakson aikana." words1 = "[:nick] on selvästi kanavan pikakirjoittaja [:words] sanalla!" words2 = "vaikka [:oldnick] vei ykkössijan tällä kertaa, on [:nick] hyvänä kakkosena [:words] sanalla." words3 = "Kukaan ei sanonut sanaakaan... Onpas omituinen kanava." mono1 = "[:nick] on puhunut paljon itsekseen. Hän on pulissut 5 rivin monologeja [:monos] kertaa!" mono2 = "Toinen yksinäinen sielu on [:nick]. Hän onnistui avautumaan 5 rivin putkissa [:monos] kertaa..." wpl1 = "[:nick] kirjoitti keskimäärin [:wpl] sanan lauseita." wpl2 = "Kanavan keskiarvo on [:avg] sanaa lausetta kohti." long1 = "[:nick] naputteli ennätyksellisen pitkiä rivejä, keskimäärin [:letters] merkkiä riviä kohti." long2 = "[:channel]:n keskiarvo on alhaisempi: tarkalleen ottaen keskimäärin [:avg] merkkiä riviä kohti." short1 = "[:nick] nauttii lyhyimpien lauseiden kirjoittelusta, hän kirjoitti vain [:letters] merkkiä riville." short2 = "Myös [:nick] nauttii lyhyistä riveistä: vain [:letters] merkkiä riviä kohtaan." foul1 = "[:nick] on kanavan sailori! [:per]% hänen sanoistaan olivat kirosanoja!" foul2 = "[:nick] ei osaa myöskään hallita käytöstään: [:per]% ajasta kiroilua..." foul3 = "Hmm, [:channel], tuo siveän kielen kehto! Voi kun kaikki osaisivat käyttäytyä yhtä hyvin..." foultext = "Yksi esimerkki:
     [:line]" smiles1 = "[:nick] kirkastaa päiväsi: [:per]% hänen lauseistaan sisälsivät hymiön :)" smiles2 = "[:nick] osaa iloita myös: hymiöitä piisaa [:per]% ajasta!" smiles3 = "Tällä kanavalla ei hymyile kukaan! Lopetetaanpas se surkuttelu!" sad1 = "[:nick] on aina apeana: [:per]% hänen lauseistaan sisälsivät surullisia kasvoja :(" sad2 = "[:nick] oli myös surullinen [:per]% ajasta" sad3 = "Kukaan ei surkuttele tällä kanavalla! Hyvä [:channel]! :)" month = "tammikuuta helmikuuta maaliskuuta huhtikuuta toukokuuta kesäkuuta heinäkuuta elokuuta syyskuuta lokakuuta marraskuuta joulukuuta" day = "sunnuntaina maanantaina tiistaina keskiviikkona torstaina perjantaina lauantaina" ## Topics (Topikit) bignumtopic = "Suuria lukuja" othernumtopic = "Muuta mielenkiintoista" latesttopic = "Viimeisimmät otsikot" activetimestopic = "Vuorokauden aktiivisuuden aikajakauma" activenickstopic = "Ahkerimmat höpöttäjät" activenickbyhourtopic = "Ahkerimmat kellonajan mukaan" mostwordstopic = "Käytetyimpiä sanoja" referencetopic = "Kaivatuimpia irkkaajia" urlstopic = "Kuumia linkkejä" karmatopic = "[:channel]:n karma" notopic = "Kanavalle ei koskaan vaivauduttu laittamaan topikia..." mostnickstopic = "Eniten nimimerkkejä käyttävät irkkaajat" bylinetopic = "[:date] asettanut [:nick] klo [:time]" dailyactivitytopic = "Päivittäinen aktiivisuus (viimeiset [:n] päivää)" smileytopic = "Hymiöt :-)" chartstopic = "[:channel]:n soittolista" activegenderstopic = "Aktiivisuus sukupuolen mukaan" ## Other text (Muuta sälää) totallines = "Rivien yhteismäärä: [:lines]." totalnicks = "Tilastojen ulkopuolelle jäi [:totalnicks] käyttäjää..." totaltopic = "Otsikkoa asetettiin yhteensä [:total] kertaa." nick = "Kuka?" names = "Käytetyt nimimerkit" url = "Linkki" numberlines = "Rivien määrä" randquote = "Satunnaislausahdus" userpic = "Kuva" nottop = "Seuraavat henkilöt eivät olleet niin ahkeria (rivien määrä):" word = "Sana" numberuses = "Mainittu (kertaa)" show_words = "Sanojen määrä" show_time = "Milloin?" show_wpl = "Sanaa rivillä" show_cpl = "Merkkiä rivillä" show_lastseen = " Viimeksi paikalla" lastused = "Viimeksi maininnut" lastseen1 = "Eilen" lastseen2 = "[:days] päivää sitten" today = "Tänään" karma = "Karma" goodkarma = "Hyvän karman toi" badkarma = "Pahan karman toi" pagetitle1 = "[:channel] [:network]:ssä, tilastot laatinut: [:maintainer]" pagetitle2 = "Tilastoja päivitetty viimeksi " pagetitle3 = "Tällä [:days] päivän ajanjaksolla, kanavalla [:channel] kävi yhteensä [:nicks] eri käyttäjää." stats_gen_by = "Tilastosivu laadittu [:pisg_url]:in versiota [:version] käyttäen" author = "Perl IRC Statistics Generator, kehittäjinä [:author_url] sekä muita" stats_gen_in = "Tilastojen laatimiseen käytetty aika: [:time]" hours = "tuntia" minutes = "minuuttia" seconds = "sekuntia" and = "ja" names1 = "nickiä" names2 = "nick" smiley = "Hymiö" song = "Kappale" numberplayed = "Soitettu (kertaa)" playedby = "Viimeksi soittanut" gender = "Sukupuoli" gender_b = "Botti" gender_m = "Mies" gender_f = "Nainen" # Mouse-over titles pisghomepage = "Siirry pisg:in kotisivuille" authorhomepage = "Siirry pisg:in kehittäjän kotisivuille" newwindow = "Avaa uuteen ikkunaan:" mailto = "Lähetä sähköpostia"
### Slovenian mostop1 = "[:nick] je [:podaril:podarila:] [:ops] opov na kanalu..." mostop2 = "[:nick] je [:bil:bila:] tudi zelo [:radodaren:radodarna:]. [:ops] opov od [:njega:nje:]." mostop3 = "Cudno, nikomur ni bil dan op na [:channel]!" mostdeop1 = "[:nick] je [:bil:bila:] serif tega kanala z [:deops] deopi." mostdeop2 = "[:nick] je [:odvzel:odvzela:] op [:deops] uporabnikom kanala." mostdeop3 = "Wooo...nikomu ni bil odvzet op na kanalu [:channel]!" mosthalfop1 = "[:nick] podelil [:halfops] halfop-ov na kanalu..." mosthalfop2 = "[:nick] je bil zelo vljuden: [:halfops] podeljenih halfop-ov." mosthalfop3 = "Zaèuda, ni halfop-ov na [:channel]!" mostdehalfop1 = "[:nick] je erif na kanalu z [:dehalfops] odvzetih halfop-ov." mostdehalfop2 = "[:nick] je odvzel halfop [:dehalfops] uporabnikom." mostdehalfop3 = "Wow, nobenih halfop-ov odvzetih na [:channel]!" mostvoice1 = "[:nick] je [:podaril:podarila:] [:voices] voicev na kanalu..." mostvoice2 = "[:nick] je [:bil:bila:] tudi zelo [:radodaren:radodarna:]. [:voices] voicev od [:njega:nje:]." mostvoice3 = "Cudno, nikomur ni bil dan voice na [:channel]!" mostdevoice1 = "[:nick] [:rad:rada:] jemlje voice ljudem... [:devoices] ljudi je ostalo brez voice-a zaradi [:njega:nje:]." mostdevoice2 = "[:nick] tesno sledi... [:Odvzela:Odvzel:] voice [:devoices] ljudem." mostdevoice3 = "Nihce ni nikomur odvzel voice-a na [:channel]!" action1 = "[:nick] nam je vedno [:povedal:povedala:] kaj pocne: [:actions] dejanj!" action2 = "Tudi [:nick] nam je vedno [:povedal:povedala:] kaj se je dogajalo z [:njim:njo:], [:actions] dejanj." action3 = "Nobenih dejanj na kanalu [:channel]!" actiontext = "Najbolj izstopa primer:
     [:line]" question1 = "Je [:nick] res najbolj [:neumen:neumna:] na tem kanalu ali samo sprasuje veliko vprasanj? [:per]% [:njegovih:njenih:] vrstic so bila vprasanja!" question2 = "[:nick] ni [:imel:imela:] pojma o nicemer. [:per]% [:njegovih:njenih:] vrstic so bila vprasanja." question3 = "Nihce ni nic vprasal na tem kanalu; ocitno so sami geniji na tem kanalu?" shout1 = "Najbolj [:glasen:glasna:] je [:bil:bila:] [:nick], ki se je [:drl:drla:] kar [:per]% svojega govorjenja na kanalu!" shout2 = "Naziv Hripav cucek pa dobi: [:nick], ki je z nami [:delil:delila:] [:per]% svojega lajanja na kanalu!" shout3 = "Nihce ni nikoli krical." allcaps1 = " [:nick] je [:imel:imela:] zataknjeno tipko shift: [:per]% svojega pisanja je [:pisal:pisalaa:] z VELIKIMI CRKAMI!" allcaps2 = "[:nick] je [:pozabil:pozabila:] ponovno pritisniti svojo Caps-Lock tipko. Z VELIKIMI CRKAMI je [:pisal:pisala:] kar [:per]% svojega besedicenja na kanalu." allcaps3 = "Vsi so imeli svojo shift tipko pod kontrolo. :)" allcapstext = "Ce si pogledamo tale primer:
     [:line]" violent1 = "[:nick] je zelo [:agresiven:agresivna:]. [:attacks]-krat je [:napadel:napadla:] druge ljudi na kanalu." violent2 = "[:nick] tudi ni [:znal:znala:] kontorlirati svoje jeze. Na druge se je [:spravil:spravila:] [:attacks]-krat!" violent3 = "Nihce ni nikogar napadel. Vsi so bili prijazni." violenttext = "Vzemimo primer:
     [:line]" attacked1 = "[:Bogi:Boga:] [:nick]. Nihce [:ga:je:] ne mara. [:Bil:Bila:] je [:napaden:napadena:] [:attacks]-krat." attacked2 = "Tudi [:nick] ni [:bil:bila:] najbolj [:priljubljen:priljubljena:]. [:attacks]-krat je [:dobil:dobila:] buske!." attackedtext = "Naprimer:
     [:line]" gotkick1 = "[:nick] je [:bil:bila:] ocitno zelo [:morec:moreca:], saj so [:ga:jo:] brcnili iz kanala kar [:kicks]-krat!" gotkick2 = "Tudi [:nick] je [:bil:bila:] na spisku osovrazenih ljudi, [:kicks]-krat je [:dobil:dobila:] brco." kicktext = "Kot naprimer tole:
     [:line]" joins = "[:nick] se ni [:mogel:morala:] odlociti ali naj ostane na kanalu ali naj gre dol. [:joins]-krat je [:prisel:prisla:] na kanal med tem casom, ko smo belezili statistiko!" kick1 = "[:nick] je [:bil:bila:] [:nor:nora:] [:operater:operaterka:], saj je [:brcnil:brcnila:] iz kanala [:kicked] ljudi!" kick2 = "[:Zvesti:Zvesta:] [:naslednik:naslednica:] na kanalu, [:nick], pa je [:brcnil:brcnila:] [:kicked] ljudi iz kanala." kick3 = "Kaksni dobri operaterji, nikogar niso brcnili iz kanala!" words1 = "[:nick] je [:povedal:povedala:] vsega skupaj [:words] besed!" words2 = "Sledi mu [:nick], ki pa ni kaj dosti manj [:govoril:govorila:]: [:words] besed." words3 = "Nihce ni nic rekel... Kaksen cuden kanal..." mono1 = "[:nick] je veliko [:govoril:govorila:] [:sam:sama:] s sabo. [:Napisal:Napisala:] je 5 vrstic naenkrat, kar [:monos]-krat!" mono2 = "Tudi [:nick] spada med osamljene osebe, saj je [:pisal:pisala:] [:samemu:sami:] sebi kar [:monos] krat." wpl1 = "[:nick] je [:napisal:napisala:] povprecno [:wpl] besed na vrstico." wpl2 = "Povprecje kanala [:channel] je [:avg] besed na vrstico." long1 = "[:nick] je [:pisal:pisala:] najdaljse vrstice, dolge povprecno [:letters] znakov na vrstico." long2 = "Povprecje kanala [:channel] je bilo [:avg] znakov na vrstico." short1 = "[:nick] je [:pisal:pisala:] najkrajse vrstice, ki so vsebovale samo [:letters] znakov na vrsico." short2 = "[:nick] mu je [:sledil:sledila:] z [:letters] znaki na vrstico." foul1 = "[:nick] je [:imel:imela:] umazana usta. [:per]% [:njegovih:njenih:] vrstic je vsebovalo grde besede." foul2 = "[:nick] pa ni [:zaostajal:zaostajala:] dosti, [:per]% [:njegovih:njenih:] besed so bile kletvice." foul3 = "Nihce ni grdo govoril na kanalu [:channel]! A sploh kej ven hod'te?" foultext = "Cisti primer je:
     [:line]" smiles1 = "[:nick] je [:prinasal:prinasala:] sreco na ta svet. [:per]% [:njegovih:njenih:] vrstic so bili smeskoti. :)" smiles2 = "[:nick] tudi ni zalostna oseba, saj se smeje [:per]% vsega svojega casa." smiles3 = "Nihce se ni smejal na kanalu[:channel]! Razveseliti vas bo treba fantje in punce." sad1 = "[:nick] je verjetno zelo [:zalosten:zalostna:] ta trenuek, ker je: [:per]% vrstic vsebovalo zalostne smeskote. :(" sad2 = "[:nick] je tudi zalostna oseba, saj je [:jokal:jokala:] [:per]% svojega govorjenja." sad3 = "Nihce ni zalosten na kanalu [:channel]! Kaksen vesel kanal. :-)" month = "Januar Februar Marec April Maj Junij Julij Avgust September Oktober November December" day = "Nedelja Ponedeljek Torek Sreda Cetrtek Petek Sobota" ## Topics bignumtopic = "Najvecji rekordi" othernumtopic = "Druge zanimivosti" latesttopic = "Zadnji topici" activetimestopic = "Najbolj aktivni casi" activenickstopic = "Najbolj aktivni nicki" activenickbyhourtopic = "Najbolj aktivni nicki sortirani po casu" mostwordstopic = "Najveckrat izrecene besede" referencetopic = "Najveckrat omenjen nick" urlstopic = "Najveckrat povedan URL naslov" notopic = "Na tem kanalu ni nihce nikoli postavil topica." mostnickstopic = "Uporabniki z najvec nicki" bylinetopic = "[:date] [:Povedal:Povedala:] [:nick] ob [:time]" smileytopic = "Smekoti :-)" dailyactivitytopic = "Dnevna Aktivnost (zadnjih [:n] dni)" activegenderstopic = "Najbolj Aktiven Spol" chartstopic = "[:channel] Glasbene Lestvice" karmatopic = "[:channel] karma" ## Other text totallines = "Stevilo vseh vrstic znasa: [:lines]." totalnicks = "Ce koga zanima, je bilo se [:totalnicks] drugih nickov na tem kanalu, ki pa niso dovolj pomembni da bi bili vpisani na tej strani." totaltopic = "Topic je bil postavljen [:total]-krat." nick = "Nick" names = "Imena uporabljena" url = "URL" numberlines = "Stevilo vrstic" randquote = "Nakljucni citat" userpic = "Slika" nottop = "Vsi ti, pa niso prisli med najboljse:" word = "Beseda" numberuses = "Stevilo uporab" show_words = "Stevilo besed" show_time = "Kdaj?" show_wpl = "Stevilo besed na vrstico" show_cpl = "Stevilo znakov na vrstico" show_lastseen = "Zadnjic viden/a" lastused = "Zadnjic uporabljal/a" lastseen1 = "[:days] dan nazaj" lastseen2 = "[:days] dni nazaj" today = "Danes" pagetitle1 = "Statistika kanala [:channel] na [:network]-u, ki jo vodi [:maintainer]" pagetitle2 = "Statistika generirana na dan: " pagetitle3 = "Med tem [:days]-dnevnim casom, ko je bil kanal logiran, je sestevek nickov, ki so si prisli ogledat kanal [:channel] [:nicks]" stats_gen_by = "Statistika narejena s programom [:pisg_url] v[:version]" author = "pisg napisal [:author_url] in drugi" stats_gen_in = "Statistika narejena v [:time]" hours = "urah" minutes = "minutah" seconds = "sekundah" and = "in" names1 = "imena" names2 = "ime" karma = "Karma" badkarma = "Slaba karma od" goodkarma = "Dobra karma od" smiley = "Smeko" gender = "Spol" gender_b = "Bot" gender_f = "enski" gender_m = "Moki" numberplayed = "Koliko Pogosto Zaigran" song = "Pesem" playedby = "Zadnje Zaigrana od" # Mouse-over titles pisghomepage = "Pojdi na domaco stran programa pisg" authorhomepage = "Pojdi na avtorjevo domaco stran" newwindow = "Odpri v novem oknu:" mailto = "Poslji mail na:"
### Hungarian (Magyar lengvidzsu szovegek) mostop1 = "[:nick] [:ops] opot adott a csatin..." mostop2 = "[:nick] szinten nagylelku: [:ops] opot adomanyozott." mostop3 = "Erdekes, senki nem kapott opot a [:channel] csatin!" mostdeop1 = "[:nick] volt a csati rendore, [:deops] alkalommal deopolt." mostdeop2 = "[:nick] deopolt [:deops] emberket." mostdeop3 = "Hu, nem vettek el egy opot sem a [:channel]-n!" mostvoice1 = "[:nick] [:voices] voice-ot adott a csatin..." mostvoice2 = "[:nick] szinten nagylelku: [:voices] voice-ot adomanyozott." mostvoice3 = "Erdekes, senki nem kapott voice-ot a [:channel] csatin!" mostdevoice1 = "[:nick] szereti elvenni a voice-ot, [:devoices] alkalommal tette ezt." mostdevoice2 = "[:nick] hasonloan [:devoices] embertol vette el a voice-ot." mostdevoice3 = "Nem vettek el senkitol voice-ot a [:channel]-n!" mosthalfop1 = "[:nick] [:halfops] felopot adott a csatin..." mosthalfop2 = "[:nick] szinten nagylelku: [:halfops] felopot adomanyozott." mosthalfop3 = "Erdekes, senki nem kapott felopot a [:channel] csatin!" mostdehalfop1 = "[:nick] volt a csati rendore, [:deops] alkalommal vett el felopot." mostdehalfop2 = "[:nick] [:dehalfops]-szor fosztott meg valakit a felopjatol." mostdehalfop3 = "Nem vettek el egy felopot sem a [:channel]-n!" action1 = "[:nick] mindig tudatja velunk mit csinal: [:actions] akciot nyomott!" action2 = "A masodik [:nick], aki [:actions] alkalommal mondta el, mi a helyzet vele." action3 = "Semmi ekson nem volt a [:channel]-n!" actiontext = "Peldaul:
     [:line]" question1 = "[:nick] kerdez a legtobbet, a sorainak a [:per]%-a tartalmazott kerdest." question2 = "[:nick] se tud sokkal tobbet. O [:per]%-ban tett fel kerdeseket." question3 = "Senki sem kerdezett a csatin - csak zsenik jarnak ide?" shout1 = "A leghangosabb [:nick] volt, [:per]%-ban kiabalt!" shout2 = "A masik nagyhangu [:nick] volt, aki [:per]%-ban volt hangos!" shout3 = "Senki sem kiabalt." allcaps1 = "Ugy tunik [:nick] shift-gombja beragadt: [:per]%-ban NAGY BETUVEL irt." allcaps2 = "[:nick] is elfelejtette neha kikapcsoli a Caps-Lockot. [:per]%-ban NAGYBETUZOTT." allcaps3 = "Mindenki ugyelt a shiftre." allcapstext = "Peldaul:
     [:line]" violent1 = "[:nick] meglehetosen agressziv. [:attacks]-szer/szor bantott masokat." violent2 = "[:nick] sem tudott uralkodni magan [:attacks] alkalommal." violent3 = "Senki sem bantott senkit." violenttext = "Peldaul igy:
     [:line]" attacked1 = "Szegeny [:nick]-t nem nagyon szeretik. [:attacks] alkalommal bantottak." attacked2 = "[:nick] is sokat bantjak. Ot [:attacks]-szer/szor bantottak." attackedtext = "Peldaul:
     [:line]" gotkick1 = "[:nick] nem volt tul nepszeru, [:kicks]-szer/szor kirugodott!" gotkick2 = "[:nick] Sem nagy koma, o [:kicks] kicket kapott." kicktext = "Peldaul, mint ez:
     [:line]" joins = "[:nick] jott be a legtobbszor. [:joins] alkalommal a logolas alatt." kick1 = "[:nick] vagy kocsog, vagy jo op, kirugott [:kicked] embert." kick2 = "[:oldnick] lelkes kovetoje, [:nick], szinten kirugott [:kicked] komat." kick3 = "Aranyosak az opok, senkit sem rugtak ki." words1 = "[:nick] [:words] szot mondott!" words2 = "[:oldnick] utan a masodik [:nick] alig [:words] szoval." words3 = "Erdekes hely, senki nem mond semmit..." mono1 = "[:nick] tul sokat beszel magaban. Tobb, mint 5 sort irt le egymas utan [:monos] alkalommal!" mono2 = "A masik magaban beszelo [:nick] volt, aki hasonloan tett [:monos]-szer/szor." wpl1 = "[:nick] atlagosan [:wpl] szot ir soronkent." wpl2 = "A csati atlaga [:avg] szo/sor." long1 = "[:nick] irja a leghosszabb sorokat, atlagosan [:letters] betut soronkent." long2 = "[:channel] atlag: [:avg] betu/sor." short1 = "[:nick] irja a legrovidebb sorokat, atlagosan [:letters] betut soronkent." short2 = "[:nick] szinten szukszaju a(z) [:letters] betu/soros atlagaval." foul1 = "[:nick] csunyan beszel. a sorai [:per]%-a tartalmaz csunya szot." foul2 = "[:nick] szinten nem beszel eleg szepen az esetek [:per]%-aban." foul3 = "Senki nem beszel csunyan a [:channel]-n!" foultext = "Peldaul, mint itt:
     [:line]" smiles1 = "[:nick] a legvidamabb. A sorai [:per]%-aban mosolyog :)" smiles2 = "[:nick] sem egy szomorkas egyen, az ido [:per]%-aban vigyorog." smiles3 = "Senki sem mosolygott?!" sad1 = "[:nick] szomorunak tunik: a sorai [:per]%-a tartalmaz szomorkodast. :(" sad2 = "[:nick] szinten nem tul vidam, szomoru az esetek [:per]%-aban." sad3 = "Itt senki sem szomoru!:)" month = "Januar Februar Marcius Aprilis Majus Junius Julius Augusztus Szeptember Oktober November December" day = "Vasarnap Hetfo Kedd Szerda Csutortok Pentek Szombat" ## Topics bignumtopic = "Nagy szamok" othernumtopic = "Egyeb erdekes szamok" latesttopic = "Legutobbi topicok" activetimestopic = "Legaktivabb idoszakok" activenickstopic = "Legaktivabb nevek" activenickbyhourtopic = "Legaktivabb nevek - orakra bontva" mostwordstopic = "Legtobbet hasznalt szavak" referencetopic = "Legtobbet emlegetett nevek" urlstopic = "Legtobbet emlitett URL-ek" notopic = "A topic sosem valtozott." mostnickstopic = "Legtobb nicknevet hasznalo csetelok" bylinetopic = "[:date] [:nick] allitotta be [:time]-kor." smileytopic = "Szmájlik" chartstopic = "[:channel] Slagerlista" karmatopic = "[:channel] karma" dailyactivitytopic = "Napi aktivitás (utolsó [:n] nap)" activegenderstopic = "Nemek szerinti aktivitas" ## Other text totallines = "Osszes sorok szama: [:lines]." totalnicks = "Mellesleg osszesen [:totalnicks] nick volt a csatin." totaltopic = "A topicot [:total]-szer/szor valtoztattak meg." nick = "Nick" url = "URL" numberlines = "Sorok szama" randquote = "Veletlen sor" userpic = "Kep" nottop = "Nem kerultek be a legjobbak koze:" word = "Szo" numberuses = "Hasznalatok szama" show_words = "Szavak szama" show_time = "Mikor?" show_wpl = "Szo/sor" show_cpl = "Betu/sor" show_lastseen = "Utoljara itt:" lastused = "Utoljara hasznalta:" pagetitle1 = "[:channel] @ [:network] statisztika [:maintainer] segitsegevel" pagetitle2 = "A statisztika: " pagetitle3 = "Ezalatt a [:days] napos idoszak alatt [:nicks] kulonbozo nick-u emberke tevekenykedett a [:channel]-n." today = "Ma" lastseen1 = "[:days] nappal ezelott" lastseen2 = "[:days] nappal ezelott" stats_gen_by = "A statisztikat keszitette: [:pisg_url] v[:version]" author = "pisg keszitoje: [:author_url] and others" stats_gen_in = "A statisztika keszult: [:time]" hours = "ora" minutes = "perc" seconds = "masodperc" and = "es" names1 = "nevek" names2 = "nev" names = "Használt nevek" karma = "Karma" badkarma = "Rossz karma ... miatt/által" goodkarma = "Jó karma ... miatt/által" smiley = "Szmájli" gender = "Neme" gender_b = "Robot" gender_f = "Nõ" gender_m = "Férfi" numberplayed = "Milyen gyakran játszott" song = "Dal" playedby = "Utoljára játszott" # Mouse-over titles pisghomepage = "A pisg honlapja" authorhomepage = "A keszito honlapja" newwindow = "Uj ablakban nyitas:" mailto = "Level kuldese:"
### Estonian mostop1 = "Kõige rohkem operaatori staatust jagas [:nick], [:ops] korda." mostop2 = "[:nick] ei tahtnud sitem olla ja andis [:ops] op-i." mostop3 = "Imelik, aga kanalil [:channel] ei andnud keegi kellelegi op-i!" mostdeop1 = "[:nick] mõtles, et on kõva kutt ja võttis [:deops]-lt kasutajalt op-staatuse ära." mostdeop2 = "[:nick] deop-is [:deops] kasutajat." mostdeop3 = "Ohoh, keegi ei võtnud kelleltki op-i ära!" mostvoice1 = "[:nick] andis [:voices]-le kasutajale hääle." mostvoice2 = "[:nick] oli ka väga lahke ja andis [:voices] häält." mostvoice3 = "Imelik, kanalis [:channel] ei antud ühtegi häält!" mostdevoice1 = "[:nick]'le meeldib teistelt hääli ära võtta, tegi seda [:devoices] korda." mostdevoice2 = "Samas [:nick] võttis [:devoices]-lt kasutajalt hääle ära." mostdevoice3 = "Ühtegi häält ei võetud ära!" mosthalfop1 = "[:nick] andis [:halfops] poolikut op-i kanalis..." mosthalfop2 = "[:nick] andis kah mõned poolikud operaatorid ja ta tegi seda [:halfops]-l korral." mosthalfop3 = "Imelik, ühtegi pool-operaatori staatust ei antud [:channel] kanalis!" mostdehalfop1 = "Kuri [:nick] võttis [:dehalfops] korda teistelt pool-operaatori staatuse." mostdehalfop2 = "[:nick] võttis [:dehalfops]-lt kasutajalt pooliku op-i." mostdehalfop3 = "Ohoo, ühtegi pool-operaatori staatust ei võetud [:channel] kanalis!" action1 = "[:nick] tahtis, et kõik teaksid, mida ta teeb: kokku [:actions] tegevust!" action2 = "Kusjuures, [:nick] tahtis ka, et kõik teaksid tema tegevusest: kokku [:actions] tegevust." action3 = "Mitte ühtegi tegevuse kirjeldust selle perioodi jooksul!" actiontext = "Nagu näiteks:
     [:line]" question1 = "Tundub, et [:nick] on mingi eriti loll tegelane või esitab ta lihtsalt liiga palju küsimusi? [:per]% ridadest olid küsimused." question2 = "[:nick] ei teadnud ka kuigi palju: [:per]% ridadest olid küsimused." question3 = "Keegi ei esitanud küsimusi, tundub et siin kanalis käivad ainult targad inimesed" shout1 = "Kõige suurem kisakõri oli [:nick], [:per]% ajast ainult lõugas ja näitas hambaid teistele." shout2 = "Teine kõvema häälega tüüp oli [:nick], tema valju hääle osakaal oli [:per]%." shout3 = "Lahe! Kõik rääkisid vaikse häälega." allcaps1 = "Tundub et [:nick] shift'i nupp vajub iseenesest alla: [:per]% ajast kirjutas SUURTE TÄHTEDEGA." allcaps2 = "[:nick] unustas oma Caps-Lock'i peale. [:per]% ajast kirjutas SUURTE TÄHTEDEGA." allcaps3 = "Kõik kirjutasid väikeste tähtedega. :)" allcapstext = "Nagu näiteks:
     [:line]" violent1 = "[:nick] on väga agressiivne persoon. Ta peksis teisi [:attacks] kord(a)." violent2 = "[:nick] ei suuda sammuti end vaos hoida ja lõi teisi [:attacks] kord(a)." violent3 = "[:channel] kanalis käib väga sõbralik rahvas, keegi ei löönud teisi" violenttext = "Nagu näiteks:
     [:line]" attacked1 = "Vaene [:nick], ta ei meeldi vist teistele. Teda rünnati [:attacks] kord(a)." attacked2 = "Samas [:nick] sai [:attacks] kord(a) kolakat." attackedtext = "Nagu näiteks:
     [:line]" gotkick1 = "[:nick] ei olnud eriti populaarne, ta sai [:kicks] kord(a) saabast!" gotkick2 = "[:nick] polnud ka eriti popp: talle tehti [:kicks] kord(a) lennukit." kicktext = "Nagu näiteks:
     [:line]" joins = "[:nick] ei suutnud otsustada, kas jääda kanalisse või mitte. Liitus kanaliga [:joins] korda!" kick1 = "[:nick] on mingi päris karm vend või siis lihtsalt õiglane operaator: [:kicked] inimest said kinga!" kick2 = "Noh [:nick] mõtles, et näitab ka oma võimu ja andis [:kicked] saabast." kick3 = "Kõik käitusid hästi ja keegi ei saanud kick'i!" words1 = "[:nick] kirjutas kokku [:words] sõna!" words2 = "[:nick] rääkis natuke vähem kui [:oldnick]: [:words] sõna." words3 = "Keegi ei öelnud mitte kui midagi... Väga imelik kanal..." mono1 = "[:nick] rääkis väga palju omaette. Ta kirjutas rohkem kui 5 rida järjest [:monos]-l korral!" mono2 = "Väga üksikuna tundis ennast [:nick] ja seda [:monos]-l korral." wpl1 = "[:nick] kirjutas keskmiselt [:wpl] sõna rea kohta." wpl2 = "Kanali keskmine oli [:avg] sõna rea kohta." long1 = "[:nick] kirjutas kõige pikemaid ridu, keskmiselt [:letters] tähte reas." long2 = "[:channel] keskmine oli [:avg] tähte reas." short1 = "[:nick] kirjutas kõige lühemaid ridu, keskmiselt [:letters] sümbolit reas." short2 = "[:nick] kirjutas natuke pikemaid ridu, keskmiselt [:letters] sümbolit reas." foul1 = "[:nick] oli kõige ropuma suuga. [:per]% ridadest sisaldasid roppust." foul2 = "Samas [:nick] rääkis kah rumalusi, seda siis [:per]% ajast." foul3 = "[:channel] kanalit külastab väga distsiplineeritud rahvas!" foultext = "Nagu näiteks:
     [:line]" smiles1 = "[:nick] on [:channel] kanali kõige õnnelikum inimene. [:per]% ridadest sisaldasid naerunägu. :-)" smiles2 = "[:nick] pole ka just kõige kurvem inimene, naeratas [:per]% ajast." smiles3 = "Ehh, [:channel] kanalis käivad mingid imelikud. Mitte keegi ei naeratanud." sad1 = "[:nick] tundub olevat kuidagi kurvas meeleolus: [:per]% ridadest sisaldasid kurba nägu. :(" sad2 = "[:nick] on ka millegipärast pahur, tema mossitas [:per]% ajast." sad3 = "Lahe! Kõik [:channel] tegelased on heas tujus :-)" month = "Jaanuaril Veebruaril Märtsil Aprillil Mail Juunil Juulil Augustil Septembril Oktoobril Novembril Detsembril" day = "Pühapäeval Esmaspäeval Teisipäeval Kolmapäeval Neljapäeval Reedel Laupäeval" # Topics bignumtopic = "Suured numbrid" othernumtopic = "Teisi huvitavaid numbreid" latesttopic = "Hiljutised teemad" activetimestopic = "Kõige aktiivsem aeg" activenickstopic = "Kõige aktiivsemad kasutajad" activenickbyhourtopic = "Aktiivseimad kasutajad tundide järgi võetuna" mostwordstopic = "Eelistatuimad sõnad" referencetopic = "Enim mainitud nimed" karmatopic = "[:channel] karma" urlstopic = "Kõige enam mainitud viited" notopic = "Kanali teemat ei muudetud kordagi." mostnickstopic = "Kasutajad, kes armastavad tihti oma nime muuta" bylinetopic = "[:date] muutis [:nick] kell [:time]" dailyactivitytopic = "Päevane aktiivsus (viimased [:n] päeva)" activegenderstopic = "Kõige aktiivsem sugu" smileytopic = "Smailid :-)" chartstopic = "[:channel] muusika edetabelid" # Other text totallines = "Ridade arv kokku: [:lines]" totalnicks = "Muideks, kanalit külastas veel [:totalnicks] tegelast." totaltopic = "Teemat muudeti [:total] korda." nick = "Nimi" names = "Erinevad nimed" url = "URL" numberlines = "Ridade arv" randquote = "Suvaline tsitaat" userpic = "Kasutaja pilt" nottop = "Nemad ei küündinud nii kõrgele:" word = "Sõna" numberuses = "Kasutatavus" show_words = "Sõnade arv" show_time = "Aeg" show_wpl = "Sõnade arv reas" show_cpl = "Tähtede arv reas" show_lastseen = "Viimati ajas juttu" lastused = "Viimati kasutas" karma = "Karma" goodkarma = "Hea karma pani" badkarma = "Halva karma pani" lastseen1 = "Eile" lastseen2 = "[:days] päev tagasi" today = "Täna" pagetitle1 = "[:channel] @ [:network] statistika koostas [:maintainer]" pagetitle2 = "Statistika on koostatud" pagetitle3 = "[:days]-päevase perioodi jooksul külastas [:channel] kanalit [:nicks] erinevat tegelast." stats_gen_by = "Statistika genereeris [:pisg_url] v[:version]" author = "pisg'i autor on [:author_url] ja teised" stats_gen_in = "Statistika koostamine võttis aega [:time]" hours = "tund(i)" minutes = "minut(it)" seconds = "sekund(it)" and = "ja" names1 = "nime" names2 = "nimi" gender = "Sugu" gender_f = "Naine" gender_m = "Mees" gender_b = "Robot" smiley = "Smaili" song = "laul" numberplayed = "kui tihti mängitud" playedby = "viimati mängis" # Mouse-over titles pisghomepage = "pisg kodulehele" authorhomepage = "Autori kodulehele" newwindow = "Ava uues aknas:" mailto = "Postita kiri aadressile"
### Italian mostop1 = "[:nick] ha fatto [:ops] operatori..." mostop2 = "Anche [:nick] è stato molto gentile: [:ops] operatori da [:him:her:]." mostop3 = "Strano, nessuno è stato reso operatore su [:channel]!" mostdeop1 = "[:nick] è lo sceriffo del canale con [:deops] declassamenti." mostdeop2 = "[:nick] ha tolto lo status di operatore a [:deops] utenti." mostdeop3 = "Uau, a nessuno è stato tolto lo status di operatore su [:channel]!" mostvoice1 = "[:nick] ha dato voce a [:voices] utenti nel canale..." mostvoice2 = "Anche [:nick] è stato molto gentile: voce a [:voices] utenti da [:him:her:]." mostvoice3 = "Strano, a nessuno è stato dato voce su [:channel]!" mostdevoice1 = "[:nick] ama togliere la voce alle persone, lo ha fatto ben [:devoices] volte." mostdevoice2 = "[:nick] lo segue a routa, infatti ha ammutolito [:devoices] utenti." mostdevoice3 = "Uau, nessuno è stato zittito su [:channel]!" mosthalfop1 = "[:nick] ha fatto [:halfops] mezzoperatori..." mosthalfop2 = "Anche [:nick] è stato molto gentile: [:halfops] mezzoperatori da [:him:her:]." mosthalfop3 = "Strano, nessuno è stato reso mezzoperatore su [:channel]!" mostdehalfop1 = "[:nick] è lo sceriffo del canale con [:dehalfops] declassamenti." mostdehalfop2 = "[:nick] ha tolto lo status di mezzoperatore a [:dehalfops] utenti." mostdehalfop3 = "Uau, a nessuno è stato tolto lo status di mezzoperatore su [:channel]!" action1 = "[:nick] vuole sempre farci sapere cosa sta facendo: [:actions] azioni!" action2 = "Inoltre, [:nick] ci dice cosa c'è con [:actions] azioni." action3 = "Niente azioni in [:channel]!" actiontext = "Ad esempio, così:
     [:line]" question1 = "Ma [:nick] è stupido o solo fa troppe domande?! Ben il [:per]% delle linee contengono una domanda!" question2 = "Anche [:nick] non ne sà così tanto. Il [:per]% delle linee erano domande." question3 = "Nessuno ha fatto domande qui, solo geni in questo canale?" shout1 = "Il più rumoroso è stato [:nick], che ha strillato il [:per]% del tempo!" shout2 = "Un altro vecchio strillone è [:nick], che ha urlato per il [:per]% del tempo!" shout3 = "Nessuno ha urlato per nulla, uau." allcaps1 = "Sembra che il tasto shift di [:nick] sia bloccato: per il [:per]% del tempo ha scritto in MAIUSCOLO." allcaps2 = "[:nick] ha dimenticato di spegnere il suo CapsLock. Ha scritto in MAIUSCOLO per il [:per]% del tempo." allcaps3 = "Tutti hanno tenuto sotto controllo il tasto shift. :-)" allcapstext = "Ad esempio, così:
     [:line]" violent1 = "[:nick] è una persona molto aggressiva, ha attaccato gli altri [:attacks] volte." violent2 = "Anche [:nick] non riesce a controllare l'aggressività. Ha assalito gli altri [:attacks] volte." violent3 = "Nessuno picchia nessuno. Sono tutti amichevoli." violenttext = "Ad esempio, così:
     [:line]" attacked1 = "Povero [:nick], non piace a nessuno. È stato attaccato [:attacks] volte." attacked2 = "Anche [:nick] sembra che piaccia poco. Le ha prese [:attacks] volte." attackedtext = "Ad esempio, così:
     [:line]" gotkick1 = "[:nick] non è molto popolare, è stato cacciato [:kicks] volte!" gotkick2 = "Anche [:nick] sembra sia odiato: ha ricevuto ben [:kicks] calci." kicktext = "Ad esempio, così:
     [:line]" joins = "[:nick] non sa se stare o andare. È entrato [:joins] volte durante questo periodo in esame!" kick1 = "[:nick] è forse folle o solo un operatore corretto, ha cacciato un totale di [:kicked] persone!" kick2 = "Il fedele seguace di [:oldnick], [:nick], ha cacciato circa [:kicked] persone." kick3 = "Sono carini gli operatori qui, nessuno è stato cacciato!" words1 = "[:nick] ha detto un totale di [:words] parole!" words2 = "Il fedele seguace di [:oldnick], [:nick], non parla così tanto: [:words] parole." words3 = "Nessuno ha detto nulla... Che strano canale..." mono1 = "[:nick] parla con sè un bel po'. Ha scritto più di 5 linee di fila [:monos] volte!" mono2 = "Un'altro solitario è [:nick], che è riuscito a raggiungere le [:monos] volte." wpl1 = "[:nick] ha scritto una media di [:wpl] parole per linea." wpl2 = "La media del canale è di [:avg] parole per linea." long1 = "[:nick] ha scritto le linee più lunghe, in media [:letters] lettere per linea." long2 = "La media di [:channel] e' di [:avg] lettere per linea." short1 = "[:nick] ha scritto le linee più corte, in media [:letters] lettere per linea." short2 = "Anche [:nick] è di poche parole, in media [:letters] lettere per linea." foul1 = "[:nick] è piuttosto sboccato. Il [:per]% delle parole erano parolacce." foul2 = "Anche [:nick] farebbe impallidire uno scaricatore di porto, il [:per]% del tempo." foul3 = "Nessuno è sboccato in [:channel]! Sorpreso?" foultext = "Ad esempio, così:
     [:line]" smiles1 = "[:nick] porta felicità al mondo. Il [:per]% delle linee contengono facce sorridenti. :-)" smiles2 = "Neanche [:nick] e' una persona triste, sorride il [:per]% del tempo." smiles3 = "Nessuno ride qui in [:channel]! State su ragazzi e ragazze." sad1 = "[:nick] sembra essere triste al momento: il [:per]% delle linee contengono facce tristi. :-(" sad2 = "Anche [:nick] è una persona triste, piange il [:per]% del tempo." sad3 = "Nessuno e' triste in [:channel]! Che canale felice. :-)" month = "Gennaio Febbraio Marzo Aprile Maggio Giugno Luglio Agosto Settembre Ottobre Novembre Dicembre" day = "Domenica Lunedi Martedi Mercoledi Giovedi Venerdi Sabato" ## Topics bignumtopic = "Grandi cifre" othernumtopic = "Altri numeri interessanti" latesttopic = "Ultimi temi" activetimestopic = "Periodi più attivi" activenickstopic = "Persone più attive" activenickbyhourtopic = "Pseudonimi più attivi divisi per ora" mostwordstopic = "Parole più usate" referencetopic = "Pseudonimi più nominati" karmatopic = "Il karma di [:channel]" urlstopic = "Indirizzi più citati" notopic = "Un tema non è mai stato impostato in questo canale." mostnickstopic = "Utenti con più pseudonimi" bylinetopic = "alle [:time] di [:date] da [:nick]" dailyactivitytopic = "Attivita giornaliera (ultimi [:n] giorni)" activegenderstopic = "Genere più attivo" smileytopic = "Smileys :-)" chartstopic = "[:channel] Classifica Musicale" ## Other text totallines = "Numero totale di linee: [:lines]." totalnicks = "A proposito, ci sono stati [:totalnicks] altri pseudonimi." totaltopic = "Il tema è stato impostato [:total] volte." nick = "Pseudonimo" names = "Nomi Usati" url = "Indirizzo" numberlines = "Numero di linee" randquote = "Citazione casuale" userpic = "Foto dell'utente" nottop = "Questi non ce l'hanno fatta del tutto:" word = "Parola" numberuses = "Numero di utilizzi" show_words = "Numero di parole" show_time = "Quando?" show_wpl = "Parole per linea" show_cpl = "Lettere per linea" show_lastseen = "Ultima Visita" lastused = "Usato per ultimo da" karma = "Karma" goodkarma = "Buon karma da" badkarma = "Cattivo karma " lastseen1 = "ieri" lastseen2 = "[:days] giorni fa" today = "oggi" pagetitle1 = "Statistiche del canale [:channel] della rete [:network] da [:maintainer]" pagetitle2 = "Statistiche generate " pagetitle3 = "Durante questi [:days] giorni di analisi, [:nicks] pseudonimi differenti si sono visti su [:channel]." stats_gen_by = "Statistiche generate tramite [:pisg_url] [:version]" author = "pisg da [:author_url] e altri :-)" stats_gen_in = "Statistiche generate in [:time]" hours = "ore" minutes = "minuti" seconds = "secondi" and = "e" names1 = "nomi" names2 = "nome" gender = "Genere" gender_f = "Femmina" gender_m = "Maschio" gender_b = "Bot" smiley = "Smiley" numberplayed = "Quante volte è stata ascoltata" song = "Canzone" playedby = "Ascoltato l'ultima volta da" # Mouse-over titles pisghomepage = "Vai al sito di pisg" authorhomepage = "Vai al sito dell'autore" newwindow = "Apri in un'altra finestra:" mailto = "Scrivi a"
### Catalan mostop1 = "[:nick] ha donat [:ops] ops al canal..." mostop2 = "[:nick] tambe reparteix ensiamades: [:ops] ni més ni menys" mostop3 = "Encara no s'han repartit les arrobes al canal [:channel]!" mostdeop1 = "[:nick] és el dolent de la pel·lícula, ha tret l'@ a [:deops] persones" mostdeop2 = "[:nick] li ha tret l'@ a [:deops] persones" mostdeop3 = "Per ara no se li ha tret l'arroba a ningú a [:channel]!" mosthalfop1 = "[:nick] ha donat [:halfops] mig-ops en el canal..." mosthalfop2 = "[:nick] va anar també molt cortès: %[:halfops] mig-ops des de %[:him:her:]." mosthalfop3 = "Extrany, ningú ha donat mig-op en [:channel]!" mostdehalfop1 = "[:nick] és el sheriff del canal amb [:dehalfops] mig-ops." mostdehalfop2 = "[:nick] ha retirat [:dehalfops] mig-ops als usuaris." mostdehalfop3 = "Uau, ningú mig-op va ser pres en [:channel]!" question1 = "[:nick] necessitava més hores de guarderia quan era petit/a, el [:per]% de les seves linies contenen una pregunta!" question2 = "[:nick] tampoc s'entera gaire el [:per]% de les seves linies són preguntes" question3 = "Ningú fa preguntes aquí, sembla un canal de savis" shout1 = "Em sembla que [:nick] està una mica exaltat/da. Escriu amb exclamacions el [:per]% del temps!" shout2 = "A [:nick] també li agrada afirmar amb rotunditat el que diu. Escriu amb exclamacions el [:per]% del temps!" shout3 = "Ningú ha escrit frases amb exclamacions." allcaps1 = "A [:nick] se li ha encallat el bloqueig de majúscules, el [:per]% del temps escriu D'AQUESTA MANERA TAN PECULIAR" allcaps2 = "[:nick] deu tenir el vici amb la tecla shift, el [:per]% del temps fa el mateix" allcaps3 = "Tothom té la tecla shift sota control :)" allcapstext = "Com per exemple, això:
     [:line]" violent1 = "[:nick] és el més agressiu del canal, ha repartit hòsties [:attacks] vegades." violent2 = "[:nick] té la mà fluixa. Ha repartit pinyes [:attacks] vegades." violent3 = "Ningú ha repartit pinyus en aquest canal, tothom -sembla- amigable :)." violenttext = "Com és mostra aqui:
     [:line]" attacked1 = "Pobre [:nick], A ningú li cau bé. Li han donat [:attacks] bofetades." attacked2 = "[:nick] té marques de dits a la cara. Ha estat abofetejat [:attacks] vegades." attackedtext = "Exemple:
     [:line]" gotkick1 = "[:nick] ha estat una mica capullo i per això el vam fer fora [:kicks] vegades!" gotkick2 = "[:nick] també ens toca bastant els ous i per això el vam fotre fora [:kicks] vegades" joins = "[:nick] no sap si marxar o quedar-se, l'he vist [:joins] vegades entrar al canal!" kick1 = "[:nick] actua com un operador amb una mà dura, ha fet fora a [:kicked] persones!" kick2 = "[:oldnick] té un seguidor incondicional, [:nick] vols sembla que fa algo hi ha expulsat a [:kicked] persones" kick3 = "És maca la gent d'aqui, ningú ha estat kickejat!" kicktext = "Aquí està la prova:
     [:line]" action1 = "[:nick] vol mantenir-nos informats del que fa en tot moment. Ha escrit [:actions] accions!" action2 = "I per suposat [:nick] també ens ho ha dit [:actions] cops" action3 = "Eh! s'han mostrat més accions a [:channel] !" actiontext = "Heus aquí un exemple:
     [:line]" words1 = "[:nick] ha dit un total de [:words] paraules!" words2 = "El fan numero 1 de [:oldnick] és [:nick], que ha escrit [:words] paraules." words3 = "Ningú diu res... quin canal més misterióso..." wpl1 = "[:nick] Ha escrit una mitjana de [:wpl] paraules per linia..." wpl2 = "La mitjana del canal és de [:avg] paraules per linia." mono1 = "La gent passa un mica de [:nick], ha escrit més de 5 linies seguides en [:monos] ocasions!" mono2 = "Una altra persona solitaria és [:nick], que ha fet el mateix [:monos] vegades" long1 = "[:nick] escriu les linies més llargues: [:letters] lletres per linia..." long2 = "La mitjana de [:channel] és de [:avg] lletres per linia" short1 = "[:nick] és la persona més vaga escribint, amb una mitjana de [:letters] lletres per linia..." short2 = "[:nick] no és queda endarrera, amb una mitjana de [:letters]" foul1 = "[:nick] necessita que li rentin la boca amb lleixiu, un [:per]% de les seves linies contenen "paraulotes" i insults" foul2 = "[:nick] també és una mica bèstia, blasfema el [:per]% del temps" foul3 = "Sembla que tothom parla correctament a [:channel]! S'ho diuen tot a la cara?" smiles1 = "[:nick] sembla que s'hagués fumat un canuto de maria, el [:per]% de les seves linies contenen caretes somrients :)" smiles2 = "[:nick] haurà fumat alguna altra cosa, està somrient el [:per]% del temps" smiles3 = "Ningú ha somrigut a [:channel]! Anims! I que ruli!!!." sad1 = "[:nick] sembla disgustat, el [:per]% de les seves linies contenen cares tristes :(" sad2 = "[:nick] també està trist el [:per]% del temps" sad3 = "Ningú està trist a [:channel]! Aqui som tots feliços :-)" month = "Gener Febrer Març Abril Maig Juny Juliol Agost Setembre Octubre Novembre Desembre" day = "Diumenge Dilluns Dimarts Dimecres Dijous Divendres Dissabte" ## Topics bignumtopic = "Què s'ha de dir de nosaltres...?" othernumtopic = "Coses interessants" latesttopic = "Últims Topics" activetimestopic = "Hores més freqüentades" activenickstopic = "La gent que més parla" mostwordstopic = "Les paraules més utilitzades" referencetopic = "Les persones de les que més es parla" urlstopic = "URLs més freqüentment mencionades" notopic = "Encara no s'ha utilitzat el topic del canal" bylinetopic = "[:date] per [:nick] a les [:time]" mostnickstopic = "Usuaris i nicks usats" dailyactivitytopic = "Activitat diària (últims [:n] dies)" activegenderstopic = "Gènere més actiu" smileytopic = "Emoticones :-)" chartstopic = "[:channel] Èxits musicals" karmatopic = "[:channel] karma" ## Other text totallines = "Nombre total de linies: [:lines]" totalnicks = "Hi ha hagut altres [:totalnicks] nicks que han passat pel canal" totaltopic = "Hi ha hagut [:total] canvis de topic" nick = "Nick" names = "Noms utilitzats" url = "URL" numberlines = "Linies" randquote = "Frase a l'atzar" show_words = "Número de paraules" show_wpl = "Paraules per línia" show_cpl = "Caracters per línia" activenickbyhourtopic = "Els nick més actius per hores" names1 = "Noms" names2 = "Nom" mostvoice1 = "[:nick] va donar [:voices] voices al canal..." mostvoice2 = "[:nick] va ser molt amable i va donar [:voices] en total." mostvoice3 = "Que estrany, no es va donar cap voice al canal [:channel]!" mostdevoice1 = "A [:nick] li agrada molt treure voice a la gent, [:devoices] devoices en total." mostdevoice2 = "[:nick] també s'hi acosta, va treure voice a [:devoices] usuaris." mostdevoice3 = "La gent del [:channel] viu molt feliç, no es ve treure cap voice :)" foultext = "Exemple:
     [:line]" userpic = "Foto" nottop = "Ells també hi són, encara que parlin menys:" word = "Paraula" show_time = "Hora" numberuses = "Nombre d'usos" lastused = "Utilitzada per última vegada" lastseen1 = "[:days] dia fa" lastseen2 = "[:days] dies fa" pagetitle1 = "[:channel] @ [:network] estadístiques per [:maintainer]" pagetitle2 = "Estadístiques generades el " pagetitle3 = "Durant els [:days] dies d'estadístiques, [:nicks] nicks diferents han passat per [:channel]." stats_gen_by = "Stats generades per [:pisg_url] v[:version]" author = "pisg per [:author_url] i altres" stats_gen_in = "Stats generats en [:time]" hours = "hores" minutes = "minuts" seconds = "segons" and = "i" karma = "Karma" badkarma = "Malament karma per " goodkarma = "Bon kerma per" today = "Avui" show_lastseen = "Darrera visita" smiley = "Emoticona" gender = "Gènere" gender_b = "Bot" gender_f = "Femení" gender_m = "Masculí" song = "Cançó" playedby = "Última vegada reproduïda per" numberplayed = "Vegades escoltada" # Mouse-over titles pisghomepage = "Anar a la pàgina del pisg" authorhomepage = "Anar a la pàgina dels autors" newwindow = "Obrir en la finestra:" mailto = "Escriure un email a"
### Norwegian mostop1 = "[:nick] donerte [:ops] ops i kanalen.." mostop2 = "[:nick] var også veldig hyggelig: [:ops] ops fra [:ham:henne:]." mostop3 = "Merkelig, ingen op er delt ut på [:channel]!" mostdeop1 = "[:nick] er kanalens sheriff med [:deops] deops." mostdeop2 = "[:nick] deopet [:deops] brukere." mostdeop3 = "Wow, ingen er deopet på [:channel]!" mostvoice1 = "[:nick] donerte [:voices] voicer i kanalen.." mostvoice2 = "[:nick] var også veldig hyggelig: [:voices] voicer fra [:ham:henne:]." mostvoice3 = "Merkelig, ingen voice er delt ut på [:channel]!" mostdevoice1 = "[:nick] er kanalens sheriff med [:devoices] devoices." mostdevoice2 = "[:nick] devoiced [:devoices] brukere." mostdevoice3 = "Wow, ingen er devoicet på [:channel]!" mosthalfop1 = "[:nick] donerte [:halfops] halfops i denne kanalen..." mosthalfop2 = "[:nick] var også veldig vennlig: [:halfops] halfops fra [:han:henne:]." mosthalfop3 = "Rart, ingen halfop-status ble delt ut på [:channel]!" mostdehalfop1 = "[:nick] er kanalens sheriff med [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] dehalfopet [:dehalfops] brukere." mostdehalfop3 = "Wow, ingen mistet halfop-status på [:channel]!" action1 = "[:nick] passer på å fortelle oss hva [:han:hun:] gjør: [:actions] actions!" action2 = "[:nick] forteller oss også hva som skjer med [:actions] actions." action3 = "Ingen action på [:channel]!" actiontext = "For eksempel slik:
     [:line]" question1 = "Er [:nick] dum, eller stiller [:han:hun:] bare mange spørsmål? [:per]% linjer med spørsmål!" question2 = "[:nick] spør også mye. [:per]% av [:hans:hennes:] linjer er spørsmål!" question3 = "Ingen på denne kanalen stillte spørsmål. Jøss." shout1 = "Den mest bråkete er [:nick], som bråkte [:per]% av tiden!" shout2 = "En annen bråkmaker er [:nick], som skrek [:per]% av tiden!" shout3 = "Ingen bråker på denne kanalen." allcaps1 = "Det ser ut som [:nick]s shift-tast henger: [:per]% av tiden skrev [:han:hun:] STORE BOKSTAVER." allcaps2 = "[:nick] glemte nok å skru av Caps-Lock. [:Han:Hun:] skrev STORE BOKSTAVER [:per]% av tiden." allcaps3 = "Alle hadde caps lock under kontroll. Kjekt. :)" allcapstext = "For eksempel slik:
     [:line]" violent1 = "[:nick] er en aggressiv person. [:Han:Hun:] angrep andre [:attacks] ganger." violent2 = "[:nick] kan heller ikke kontrollere sin aggresjon. [:Han:Hun:] plaget andre [:attacks] ganger." violent3 = "Ingen slår hverandre. Alle er vennlige." violenttext = "For eksempel slik:
     [:line]" attacked1 = "Stakkars [:nick], ingen liker [:ham:henne:]. [:Han:Hun:] ble angrepet [:attacks] ganger." attacked2 = "[:nick] er heller ikke likt. [:Han:Hun:] ble banket [:attacks] ganger." attackedtext = "For eksempel slik:
     [:line]" gotkick1 = "[:nick] er ikke veldig populær og ble kastet ut [:kicks] ganger!" gotkick2 = "[:nick] er heller ikke populær: [:kicks] kicks er notert." kicktext = "For eksempel slik:
     [:line]" joins = "[:nick] klarte ikke bestemme seg helt - [:joins] joins i denne perioden!" kick1 = "[:nick] er enten kjip eller en real op med totalt [:kicked] kicks på samvittigheten!" kick2 = "[:oldnick]s trofaste disippel, [:nick], kicket omtrent [:kicked] personer." kick3 = "Her er det bare snille ops. Ingen er kicket!" words1 = "[:nick] ytret totalt [:words] ord!" words2 = "[:oldnick] ble tett etterfulgt av [:nick] som ytret [:words] ord." words3 = "Ingen har sagt noe som helst!" mono1 = "[:nick] snakker mye med seg selv. [:Han:Hun:] skrev over 5 linjer på rad [:monos] ganger!" mono2 = "En annen ensom sjel var [:nick], som skrev over 5 linjer på rad [:monos] ganger." wpl1 = "[:nick] skrev gjennomsnittlig [:wpl] ord pr. linje." wpl2 = "Kanalgjennomsnittet er [:avg] ord pr. linje." long1 = "[:nick] skrev de lengste linjene, gjennomsnittlig [:letters] bokstaver pr. linje." long2 = "[:channel]s gjennomsnitt er [:avg] bokstaver pr linje." short1 = "[:nick] skrev de korteste linjene, gjennomsnittlig [:letters] bokstaver pr. linje." short2 = "[:nick] er også en person av få ord - [:letters] bokstaver pr. linje i gjennomsnitt." foul1 = "[:nick] må snart vaske munnen sin. [:per]% av linjene inneholdt stygt språk." foul2 = "[:nick] er heller ikke svigermors drøm, [:per]% av tiden." foul3 = "Ingen prater stygt på [:channel]!?!" foultext = "For eksempel slik:
     [:line]" smiles1 = "[:nick] bringer lykke til verden. [:per]% av [:hans:hennes:] linjer inneholdt smileansikt. :-)" smiles2 = "[:nick] er heller ikke særlig sur. [:per]% av [:hans:hennes:] linjer inneholdt et smil." smiles3 = "Ingen smiler på [:channel]! :-(" sad1 = "[:nick] er trist for øyeblikket: [:per]% linjer inneholdt :(!" sad2 = "[:nick] er heller ikke særlig blid. [:per]% av tiden." sad3 = "Ingen er triste på [:channel]! For en koselig kanal. :-)" month = "januar februar mars april may juni juli august september oktober november desember" day = "søndag mandag tirsdag onsdag torsdag fredag lørdag" names1 = "nicks" names2 = "nick" gender = "kjønn" gender_f = "hun" gender_m = "han" gender_b = "bot" ## Topics smileytopic = "Smileys :-)" chartstopic = "Musikk Liste" mostnickstopic = "Brukere med flest nicks" bignumtopic = "Store tall" othernumtopic = "Andre interessante tall" latesttopic = "Siste topics" activetimestopic = "Mest aktive tider" activenickstopic = "Mest aktive nicks" activenickbyhourtopic = "Mest aktive nicks i tidsperioder" mostwordstopic = "Mest brukte ord" referencetopic = "Mest refererte nick" karmatopic = "[:channel] karma" urlstopic = "Mest refererte URLer" notopic = "Det har ikke vært satt noen topic på denne kanalen." bylinetopic = "[:date] av [:nick] klokken [:time]" dailyactivitytopic = "Daglig aktivitet (siste [:n] dager)" activegenderstopic = "Mest aktive kjønn" ## Other text totallines = "Totalt antall linjer: [:lines]." totalnicks = "Dessuten var det [:totalnicks] andre nicks." totaltopic = "Topicen er satt [:total] ganger." nick = "Nick" names = "Navn Brukt" url = "URL" numberlines = "Antall linjer" randquote = "Tilfeldig sitat" userpic = "Bilde" nottop = "Disse nådde ikke toppen:" word = "Ord" numberuses = "Antall ganger brukt" show_words = "Antall ord" show_time = "Når?" show_wpl = "Ord pr. linje" show_cpl = "Tegn pr. linje" show_lastseen = "Sist sett" lastused = "Sist brukt av" karma = "Karma" goodkarma = "God karma av" badkarma = "Dårlig karma av" lastseen1 = "[:days] dag siden" lastseen2 = "[:days] dager siden" today = "I dag" pagetitle1 = "[:channel] @ [:network] stats av [:maintainer]" pagetitle2 = "Statistikk generert" pagetitle3 = "I løpet av denne [:days]-dagers perioden var totalt [:nicks] forskjellige nick representert på [:channel]." stats_gen_by = "Stats generert av [:pisg_url] v[:version]" author = "pisg er skrevet av [:author_url] og andre" stats_gen_in = "Statistikken ble generert på [:time]" hours = "timer" minutes = "minutter" seconds = "sekunder" and = "og" numberplayed = "Hvor ofte spilt" song = "Sang" playedby = "Sist spilt av" smiley = "Smiley" # Mouse-over titles pisghomepage = "Gå til pisgs hjemmeside" authorhomepage = "Gå til utviklerens hjemmeside" newwindow = "Åpne i et nytt vindu:" mailto = "Mail til"
### Portuguese/Brazil action1 = "[:nick] sempre nos deixou por dentro do que [:ele:ela:] estava fazendo: [:actions] actions!" action2 = "[:nick] também nos contou sobre o que se passava com [:actions] actions." action3 = "Não houve actions no [:channel]!" actiontext = "Por exemplo:
     [:line]" activenickstopic = "Pessoas que mais falam" activenickbyhourtopic = "Pessoal que mais falam por hora" activetimestopic = "Horas mais frequentadas" allcaps1 = "Aparentemente a tecla shift do [:nick] está presa: [:per]% do tempo [:ele:ela:] escreveu com CAPS." allcaps2 = "[:nick] se esqueceu de desativar seu Caps-Lock. [:Ele:Ela:] escreveu com CAPS [:per]% do tempo." allcaps3 = "Todo mundo manteve sua tecla shift sobre controle :)" allcapstext = "Por exemplo:
     [:line]" and = "e" attacked1 = "Pobre [:nick], ninguém gosta [:dele:dela:]. [:Ele:Ela:] foi [:atacado:atacada:] [:attacks] vezes." attacked2 = "[:nick] parece não ser [:amado:amada:] também. [:Ele:Ela:] foi [:agredido:agredida:] [:attacks] vezes." attackedtext = "Por exemplo::
     [:line]" author = "pisg por [:author_url] e outros." authorhomepage = "Ir para o site do autor" bignumtopic = "Sobre nossos usuários" bylinetopic = "[:date] por [:nick] às [:time]" day = "Domingo Segunda-feira Terça-feira Quarta-feira Quinta-feira Sexta-feira Sábado" foul1 = "[:nick] necessita que lavem a sua boca com sabão, [:per]% de sua linhas contém um palavrão." foul2 = "[:nick] também é um boca-suja, fala palavrões em [:per]% do tempo." foul3 = "Parece que ninguém fala palavrões no [:channel]! São todos santos e/ou de família?" gotkick1 = "[:nick] não tem sido muito popular, levou chute [:kicks] vezes!" gotkick2 = "[:nick] também tem sido odiado, foi chutado [:kicks] vezes." hours = "horas" joins = "[:nick] não sabe se fica ou se vai, entrou [:joins] vezes no canal!" kick1 = "[:nick] é insano ou apenas linha dura, chutou [:kicked] pessoas!" kick2 = "[:oldnick] tem um seguidor barra-pesada, [:nick] chutou [:kicked] pessoas." kick3 = "Bons ops aqui, ninguém foi chutado." kicktext = "Por exemplo:
     [:line]" lastseen1 = "[:days] dia atrás" lastseen2 = "[:days] dias atrás" lastused = "Último uso por" latesttopic = "Últimos topics" long1 = "[:nick] escreve linhas grandes, em média [:letters] letras por linha..." long2 = "A média do [:channel] é de [:avg] letras por linha." mailto = "Email para" minutes = "minutos" mono1 = "[:nick] não tem amigos, escreveu mais de 5 linhas seguidas em [:monos] ocasiões!" mono2 = "Outra pessoa solitária é [:nick], que fez o mesmo em [:monos] vezes." month = "Janeiro Fevereiro Março Abril Maio Junho Julho Agosto Setembro Outubro Novembro Dezembro" mostdeop1 = "[:nick] é o malvado do canal, tirou op de [:deops] pessoas." mostdeop2 = "[:nick] tirou o op de [:deops] pessoas." mostdeop3 = "Incrível, nenhum op foi tirado no [:channel]!" mostdevoice1 = "[:nick] gosta de retirar o voice das pessoas, com [:devoices] devoices." mostdevoice2 = "[:nick] ficou perto do mesmo, retirando o voice de [:devoices] usuários." mostdevoice3 = "Nenhum voice foi retirado do [:channel]!" mostnickstopic = "Usuários com mais nicks" mostop1 = "[:nick] deu [:ops] ops no canal..." mostop2 = "[:nick] também não fica atrás: [:ops] ops foram dados por [:ele:ela:]." mostop3 = "É raro, porém nenhúm op foi dado no [:channel]!" mostvoice1 = "[:nick] doou [:voices] voices no canal..." mostvoice2 = "[:nick] também foi muito educado: [:voices] voices foram dados por [:ele:ela:]." mostvoice3 = "Estranho, nenhum voice foi dado no [:channel]!" mostwordstopic = "Palavras mais utilizadas" names = "Nicks utilizados" names1 = "nicks" names2 = "nick" newwindow = "Abrir em uma nova janela:" nick = "Nick" notopic = "Nunca foi usado um topic neste canal." nottop = "Falta pouco para chegarem ao topo:" numberlines = "Número de linhas" numberuses = "Número de usos" othernumtopic = "Outras coisas interessantes" pagetitle1 = "[:channel] @ [:network] - Estatísticas por [:maintainer]" pagetitle2 = "Estatísticas geradas " pagetitle3 = "Durante os [:days] dias de estatísticas, [:nicks] nicks distintos passaram pelo [:channel]." pisghomepage = "Ir para o site do pisg" question1 = "[:nick] precisava de mais horas de estudo quando criança, [:per]% de suas linhas contém uma pergunta!" question2 = "[:nick] não é muito inteligente, [:per]% de suas linhas são perguntas." question3 = "Ninguém fez perguntas aqui, são todos gênios neste canal?" randquote = "Frases randômicas" referencetopic = "Pessoas de quem mais se fala" sad1 = "[:nick] parece estar triste no momento, [:per]% linhas contém carinhas tristes :(" sad2 = "[:nick] também está triste por [:per]% do tempo." sad3 = "Ninguém está triste no [:channel]! Aqui somos todos felizes :-)" seconds = "segundos" short1 = "[:nick] é a pessoa que escreve as menores linhas, com uma média de [:letters] letras por linha..." short2 = "[:nick] não fica atrás, com uma média de [:letters] letras por linha." shout1 = "A pessoa que mais gritou foi [:nick], que escreveu com exclamações em [:per]% do tempo!" shout2 = "Quem não fica atrás é [:nick], que gritou [:per]% do tempo!" shout3 = "Ninguém escreveu frases exclamativas." show_cpl = "Caracteres por linha" show_lastseen = "Visto há" show_time = "Quando?" show_words = "Número de palavras" show_wpl = "Palavras por linha" smiles1 = "[:nick] parece ser a pessoa mais feliz do mundo, [:per]% linhas contém carinhas sorridentes :)" smiles2 = "[:nick] não é uma pessoa triste, já que sorriu [:per]% do tempo." smiles3 = "Ninguém sorriu no [:channel]! Vamos animar!!!" stats_gen_by = "Estatísticas geradas por [:pisg_url] v[:version]." stats_gen_in = "Estatísticas geradas em [:time]." today = "Hoje" totallines = "Número total de linhas: [:lines]." totalnicks = "Só para constar, houve outros [:totalnicks] nicks." totaltopic = "O tópico foi setado [:total] vezes." url = "URL" urlstopic = "URLs mais mencionadas" userpic = "Foto" violent1 = "[:nick] é uma pessoa muito agressiva. [:Ele:Ela:] atacou outras pessoas [:attacks] vezes." violent2 = "[:nick] também não consegue controlar suas agressões. [:Ele:Ela:] descontou em outras pessoas [:attacks] vezes." violent3 = "Ninguém se estranhou com ninguém. Todo mundo foi amigável." violenttext = "Por exemplo:
     [:line]" word = "Palavra" words1 = "[:nick] falou um total de [:words] palavras!" words2 = "[:oldnick] tem um seguidor fiel, [:nick], que não falou tanto: [:words] palavras." words3 = "Ninguém disse nada... Que canal estranho..." wpl1 = "[:nick] escreveu uma média de [:wpl] palavras por linha." wpl2 = "A média do canal foi de [:avg] palavras por linha." karma = "Carma" badkarma = "Mau carma por" goodkarma = "Bom carma por" smiley = "Smiley" gender = "Sexo" gender_b = "Bot" gender_f = "Feminino" gender_m = "Masculino" numberplayed = "Tocado" song = "Música" playedby = "Tocado pela última vez por" foultext = "Por exemplo, assim:
     [:line]" smileytopic = "Smileys :-)" chartstopic = "[:channel] Músicais" dailyactivitytopic = "Atividade diária (últimos [:n] dias)" activegenderstopic = "Por sexo" karmatopic = "[:channel] carma" mosthalfop1 = "[:nick] concedeu [:halfops] halfops no canal..." mosthalfop2 = "[:nick] também foi muito educado(a): [:halfops] halfops [:him:her:]." mosthalfop3 = "Estranho, não foi concedido nenhum halfop em [:channel]!" mostdehalfop1 = "[:nick] é o xerife do canal com [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] retirou halfops de [:dehalfops] usuários." mostdehalfop3 = "Wow, nenhum halfop foi pego em [:channel]!"
### Turkish mostop1 = "[:nick] kanalda [:ops] defa op verdi..." mostop2 = "[:nick] TAM [:ops] defa baskasina op verdi ." mostop3 = "Ilginc... [:channel] kanalinda hic op verilmemis!" mostdeop1 = "[:nick] [:deops] deop ile kanal serifi olmaya hak kazandi." mostdeop2 = "[:nick] TAM [:deops] kullaniciyi deop etmis." mostdeop3 = "Hey, [:channel] kanalinda hic deop olayi olmamis!" mosthalfop1 = "[:nick] bagislandi [:halfops] kanaldaki halfoplar..." mosthalfop2 = "[:nick] da cok nazik idi: [:halfops] den halfop [:him:her:]." mosthalfop3 = "Tuhaf,hiç halfop verilmedi [:channel]!" mostdehalfop1 = "[:nick] kanal serifi [:dehalfops] dehalfops ile." mostdehalfop2 = "[:nick] dehalfoplandi [:dehalfops] users." mostdehalfop3 = "Wow, kimsenin halfopu alýnmadý [:channel]!" mostvoice1 = "[:nick] TAM [:voices] kere kanalda + verdi..." mostvoice2 = "[:nick] cok iyi bir operator. [:voices] defa + verdi... " mostvoice3 = "Ilginc... [:channel] kanalinda hic + verilmiyor!" mostdevoice1 = "[:nick] kullanicilardan voice almayi seviyor... [:devoices] devoice." mostdevoice2 = "[:nick] tam [:devoices] kisiyi devoice etti.." mostdevoice3 = "[:channel] kanalinda devoice olayi olmadi!" action1 = "[:nick] her zaman bize ne yaptigini söylüyor: [:actions] aksiyon!" action2 = "Ayni zamanda, [:nick] [:actions] aksiyonla herseyini paylasanlardan." action3 = " [:channel] kanalinda aksiyon olmuyor!" actiontext = "Mesela:
     [:line]" question1 = "[:nick] aptal mi yoksa cok mu soru soruyor? Yazdiklarinin [:per]% gibi bir bölümünde soru soruyor." question2 = "[:nick] fazla bir sey bilmiyor. Yazdiklarinin [:per]%'si soru iceriyor." question3 = "Bu kanalda kimse birsey sormuyor. Bütün zekiler burada sanirim?" shout1 = "En cok bagiran[:nick], Yazdiklarinin [:per]% gibi bir kisminda bagiriyor!" shout2 = "Bagirmada eski rekortmen [:nick], [:per]% gibi bir kisimda bagiriyor!" shout3 = "Kanalda kimse bagirmiyor...Süper!" allcaps1 = "Sanirim [:nick]'in SHIFT tusu basili kalmis: yazdiklarinin [:per]% gibi bir kismi BUYUK HARF." allcaps2 = "[:nick] Caps-Lock tusunu kapamayi unutmus. [:per]% ortalama ile BUYUK HARF yaziyor." allcaps3 = "Herkes SHIFT tusunu kontrol altinda tutuyor... :)" allcapstext = "Mesela:
     [:line]" violent1 = "[:nick] tam bir manyak. Digerlerine tam [:attacks] defa saldirdi." violent2 = "[:nick] cok agresif... Digerlerine [:attacks]defa saldirdi." violent3 = "Herkes birbirini cok seviyor. " violenttext = "Mesela:
     [:line]" attacked1 = "Zavalli [:nick], kimse onu sevmiyor. Ona toplam [:attacks] defa saldirdilar." attacked2 = "[:nick] de cok sevilmiyor. Tam [:attacks] defa tokatlandi." attackedtext = "Mesela:
     [:line]" gotkick1 = "[:nick] pek sevilmiyor. [:kicks] kere kanaldan atildi!" gotkick2 = "[:nick] de sevilenlerden degil: [:kicks] defa kanaldan atildi." kicktext = "Mesela:
     [:line]" joins = "[:nick] kalmak ya da gitmek arasinda tercih yapamadi. [:joins] kere giris/cikis yapti!" kick1 = "[:nick] ya deli ya da adil bir op, [:kicked] kisiyi kanaldan atmis.!" kick2 = "[:oldnick] [:nick] tarafindan takip ediliyor, o da [:kicked] kisiyi kanaldan atmis." kick3 = "Buradaki oplar kimseyi atmiyor..." words1 = "[:nick] toplam [:words] kelime konusmus!" words2 = "[:oldnick]'in sadik takipcisi, [:nick], fazla konusmayanlardan: [:words] kelime." words3 = "Kimse konusmuyor... Ne kadar ilginc bir kanal..." mono1 = "[:nick] kendi kendine cok konusuyor. Arka arkaya [:monos] kere 5 satir yazdi!" mono2 = "[:nick] rekoru zorluyor, [:monos] kere." wpl1 = "[:nick] satir basina ortalama [:wpl] kelime yaziyor ." wpl2 = "Kanal ortalamasi satir basina [:avg] kelime." long1 = "[:nick] en uzun cümleleri kuruyor, satir basina ortalama [:letters] karakter." long2 = "[:channel] ortalamasi satir basina [:avg] karakter ." short1 = "[:nick] en kisa satirlari yaziyor, her satirda ortalama [:letters] karakter." short2 = "[:nick] konusmayanlardan, sadece [:letters] karakter." foul1 = "[:nick] biraz küfürbaz bir yapiya sahip.Yazdiklarinin [:per]% gibi bir kisminda yasak kelime var." foul2 = "[:nick] da yasak kelime kullaniyor. Onun yüzdesi ise: [:per]%" foul3 = "[:channel] kanalinda kimse küfür etmiyor!" smiles1 = "[:nick] mutluluk saciyor. Yazdiklarinin [:per]%'sinde :) var." smiles2 = "[:nick] de mutlu bir kisilik, zamaninin [:per]% gibi bir bölümünde gülüyor." smiles3 = "[:channel] kanalinda kimse gülmüyor! Canlanin millet biraz haydi hop!" sad1 = "[:nick] üzgün görünüyor... Yazdiklarinin [:per]%'sinde :( var." sad2 = "Ayni zamanda [:nick] üzgün olabilir, zamaninin [:per]%'sini aglamakla geciriyor ." sad3 = "[:channel] kanalinda uzgun kimse yok! Ne kadar mutlu bir kanal :-)" month = "Ocak Subat Mart Nisan Mayis Haziran Temmuz Agustos Eylul Ekim Kasim Aralik" day = "Pazar Pazartesi Sali Carsamba Persembe Cuma Cumartesi" names1 = "isimler" names2 = "isim" ## Topics bignumtopic = "Rekorlar" othernumtopic = "Diger ilginc sayilar" latesttopic = "En son kanal basligi" activetimestopic = "En aktif zaman araligi " activenickstopic = "En aktif rumuzlar" mostwordstopic = "En çok soylenen kelime" referencetopic = "En çok soylenen rumuz" urlstopic = "En çok ugranan Internet Adresleri" notopic = "Bu kanala hic baslik konmadi." mostnickstopic = "En çok rumuz degistiren kullanicilar" bylinetopic = "[:date] degistiren [:nick] zaman [:time]" karmatopic = "[:channel] karma" smileytopic = "Smileyler :-)" chartstopic = "[:channel] Müzik haritalarý" activenickbyhourtopic = "En aktif nickler" dailyactivitytopic = "Günlük faaliyet (last [:n] days)" activegenderstopic = "En aktif cinsiyet" ## Other text totallines = "Toplam satirlarin sayisi: [:lines]." totalnicks = "Bu arada, [:totalnicks] adet baska rumuz vardi." totaltopic = "Kanal basligi [:total] defa degistirildi." nick = "Rumuz" names = "Kullanilan isimler" url = "URL" numberlines = "Toplam satir" randquote = "Rastgele kelime" userpic = "Resim" nottop = "Listeye giremeyenler:" word = "Kelime" numberuses = "Toplam kullanim" show_words = "Toplam kelime" show_time = "Ne zaman?" show_wpl = "Her satirdaki kelime" show_cpl = "Her satirdaki karakter" show_lastseen = "En son görüldügü zaman" lastused = "En son kullanan" lastseen1 = "[:days] gün önce" lastseen2 = "[:days] gün önce" today = "Bugun" pagetitle1 = "[:network]'te [:channel] istatistikleri. Yonetici: [:maintainer]" pagetitle2 = "istatistikler asagidaki zaman dilimini kapsar " pagetitle3 = "[:days] gunluk periyotta, toplam [:nicks] farkli rumuz [:channel] kanalinda bulundu." stats_gen_by = "Istatistikler [:pisg_url] v[:version] tarafindan yaratilmistir." author = "pisg'i yazan: [:author_url] ve digerleri" stats_gen_in = "Istatistikler [:time] icinde yaratildi" hours = "saat" minutes = "dakika" seconds = "saniye" and = "ve" karma = "Karma" goodkarma = "Tarafýndan iyi karma" badkarma = "Tarafýndan kötü karma" smiley = "Smiley" foultext = "Örnegin, bunun gibi:
     [:line]" gender = "cinsiyet" gender_b = "Bot" gender_f = "Bayan" gender_m = "Bay" playedby = "Tarafindan en son calindi" numberplayed = "Hangi sýklýkta caldý" song = "Þarki" # Mouse-over titles pisghomepage = "pisg web sayfasina git" authorhomepage = "Gelistiricilerin web sayfasina git" newwindow = "Yeni pencerede ac:" mailto = "E-posta"
### Romanian mostop1 = "[:nick] a dat op de [:ops] ori..." mostop2 = "[:nick] a fost deasemenea politicos: [:ops] ops de la el." mostop3 = "Bizar, nu s-a dat nici un op pe [:channel]!" mostdeop1 = "[:nick] e sheriff-ul canalului cu [:deops] deop-uri." mostdeop2 = "[:nick] a deop-at [:deops] useri." mostdeop3 = "Wow, nici un deop nu s-a dat pe [:channel]!" mostdehalfop1 = "[:nick] este sheriff-ul canalului cu [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] dehalfoped [:dehalfops] utilizatori." mostdehalfop3 = "Wow, nici un halfop nu a fost luat in [:channel]!" mosthalfop1 = "[:nick] a donat [:halfops] halfops in canal..." mosthalfop2 = "[:nick] de asemenea au fost foarte politicosi: [:halfops] halfops de la [:him:her:]." mosthalfop3 = "Ciudat, nu s-a acordat nici un halfop in [:channel]!" mostvoice1 = "[:nick] a dat [:voices] voices pe canal..." mostvoice2 = "[:nick] a fost politicos, de asemenea: [:voices] voices de la el/ea." mostvoice3 = "Bizar, nu s-a dat nici un voice pe [:channel]!" mostdevoice1 = "Lui [:nick] ii place sa de-voice lumea: [:devoices] devoices." mostdevoice2 = "[:nick] a fost pe aproape: a dat devoice la [:devoices] useri." mostdevoice3 = "Nu s-a dat devoice pe [:channel]!" action1 = "[:nick] intotdeauna ne zice ce face: [:actions] actiuni!" action2 = "De asemenea, si [:nick] foloseste mult '/me': [:actions] actiuni." action3 = "No actions in [:channel]!" actiontext = "De exemplu:
     [:line]" question1 = "E [:nick] nestiutor, sau pune prea multe intrebari? [:per]% din liniile sale contin o intrebare!" question2 = "Nici [:nick] nu stie prea multe. [:per]% din liniile sale au fost intrebari." question3 = "Nimeni nu a intrebat nimic pe canal." shout1 = "Recordul la exclamatii e detinut de [:nick]: [:per]% !" shout2 = "Alt excitat a fost [:nick], care a strigat doar [:per]% din timp!" shout3 = "Nimeni nu a strigat, wow." allcaps1 = "Se pare ca tasta SHIFT a lui [:nick] e blocata: [:per]% din linii le-a scris cu LITERE MARI!" allcaps2 = "[:nick] a uitat sa-si dezactiveze Caps-Lockul. A scris doar [:per]% din linii cu CAPS." allcaps3 = "Nimeni n-a scris cu litere mari." allcapstext = "De exemplu:
     [:line]" violent1 = "[:nick] e o persoana foarte agresiva. I-a atacat pe altii de [:attacks] ori." violent2 = "Nici [:nick] nu se poate controla. [:attacks] atacuri." violent3 = "Nimeni n-a batut pe nimeni. Toata lumea a fost pasnica!" violenttext = "De exemplu:
     [:line]" attacked1 = "[:nick] a fost tinta a [:attacks] atacuri." attacked2 = "[:nick] a fost batut doar de [:attacks] ori." attackedtext = "De exemplu:
     [:line]" gotkick1 = "[:nick] n-a fost foarte cuminte si a fost dat afara de [:kicks] ori!" gotkick2 = "[:nick] a primit doar [:kicks] kick-uri." kicktext = "De exemplu:
     [:line]" joins = "[:nick] nu a hotarat daca sta sau pleaca. A intrat pe canal de [:joins] ori!" kick1 = "[:nick] este sau nebun, sau doar un OP bun: a dat afara [:kicked] persoane!" kick2 = "Complicele lui [:oldnick], [:nick], a dat kick la doar [:kicked] persoane." kick3 = "Operatorii au fost simpatici, nici un kick pe canal!" words1 = "[:nick] a scris un total de [:words] cuvinte!" words2 = "[:nick] incearca sa-l ajunga din urma pe [:oldnick], cu doar [:words] cuvinte." words3 = "Nimeni n-a zis nimic.. bizar canal..." mono1 = "Lui [:nick] îi place sa vorbeasca singur. A scris mai mult de 5 linii in sir de [:monos] ori!" mono2 = "Alt(a) singuratic(a) a fost [:nick], de doar [:monos] ori." wpl1 = "[:nick] a scris o medie de [:wpl] cuvinte pe linie." wpl2 = "Media canalului a fost de [:avg] cuvinte pe linie." long1 = "[:nick] a scris cele mai lungi linii, cu o medie de [:letters] litere pe linie." long2 = "Media canalului [:channel] a fost de [:avg] litere pe linie." short1 = "[:nick] a scris cele mai scurte linii: [:letters] litere pe linie." short2 = "[:nick] scrie la fel de putin, co u medie de [:letters] caractere." foul1 = "[:nick] are o gura cam spurcata. [:per]% din liniile sale contin obscenitati." foul2 = "[:nick] vorbeste ca birjarii doar [:per]% din timp." foul3 = "Nimeni nu vorbeste urat pe canal! Sunteti sanatosi?!" smiles1 = "[:nick] aduce fericire in lume. Zambeste in [:per]% din linii :)" smiles2 = "Nici [:nick] nu e o persoana trista, zambind [:per]% din timp." smiles3 = "Nimeni n-a zambit." sad1 = "[:nick] pare sa fie trist(a): [:per]% din linii contin ':('" sad2 = "[:nick] e la fel de trist(a) [:per]% din timp." sad3 = "Nimeni nu e trist pe [:channel]! Ce canal fericit. :-)" month = "Ianuarie Februarie Martie Aprilie Mai Iunie Iulie August Septembrie Octombrie Noiembrie Decembrie" day = "Duminica Luni Marti Miercuri Joi Vineri Sambata" names1 = "nume" names2 = "nume" ## Topics bignumtopic = "Recorduri" othernumtopic = "Alte cifre interesante" latesttopic = "Ultimele topic-uri" activetimestopic = "Perioadele cele mai active" activenickstopic = "Persoanele cele mai active" mostwordstopic = "Cuvintele cele mai des folosite" referencetopic = "Nick-ul chemat cel mai des" urlstopic = "Adresele cele mai frecvente" notopic = "Nu are topic." mostnickstopic = "Utilizatori cu cele mai multe nick-uri" bylinetopic = "[:date] de [:nick] la [:time]" dailyactivitytopic = "Activitate zilnica (ultimele [:n] zile)" activegenderstopic = "Cel mai activ sex" activenickbyhourtopic = "Cele mai active nick-uri pe ore" smileytopic = "Zambareti :-)" chartstopic = "[:channel] Topuri Muzicale" karmatopic = "[:channel] karma" ## Other text totallines = "Numarul total de linii: [:lines]." totalnicks = "Au mai fost inca [:totalnicks] alte nick-uri." totaltopic = "Topicul a fost pus de [:total] ori." nick = "Nick" names = "Nume folosite" url = "URL" numberlines = "Numarul de linii" randquote = "Citat personal" userpic = "Userpic" nottop = "Acestia n-au intrat in top:" word = "Cuvant" numberuses = "Numarul de folosiri" show_words = "Numarul de cuvinte" show_time = "Cand?" show_wpl = "Cuvinte pe linie" show_cpl = "Caractere pe linie" show_lastseen = "Ultima vizita" lastused = "Ultima folosire de catre" lastseen1 = "[:days] zi in urma" lastseen2 = "[:days] zile in urma" today = "Azi" pagetitle1 = "Statisticile canalului [:channel] de [:maintainer]" pagetitle2 = "Pagina generata pe data de " pagetitle3 = "In timpul acestei perioade de [:days] zile, un total de [:nicks] nick-uri diferite au fost pe [:channel]." stats_gen_by = "Statistici generate de [:pisg_url] v[:version]" author = "pisg de [:author_url] si altii" stats_gen_in = "Statistici generate in [:time]" hours = "ore" minutes = "minute" seconds = "secunde" and = "si" karma = "Karma" badkarma = "Karma negativa de" goodkarma = "Karma pozitiva de" smiley = "Zambaret" gender = "Sexul" gender_b = "Bot" gender_f = "Feminin" gender_m = "Masculin" foultext = "De exemplu, ca aceasta:
     [:line]" numberplayed = "Frecventa ascultarii" song = "Melodie" playedby = "Ultima data ascultata de" # Mouse-over titles pisghomepage = "Mergeti la pagina oficiala pisg" authorhomepage = "Mergeti la pagina autorului" newwindow = "Deschide in fereastra noua:" mailto = "Email catre"
### Icelandic mostop1 = "[:nick] gaf [:ops] op á rásinni..." mostop2 = "[:nick] var líka mjög kurteis: [:ops] op frá [:honum:henni:]." mostop3 = "Skrítið, engin op voru gefin á [:channel]!" mostdeop1 = "[:nick] er varðstjóri rásarinnar með [:deops] deop." mostdeop2 = "[:nick] deopaði [:deops] manns." mostdeop3 = "Vá, enginn var deopaður á [:channel]!" mostvoice1 = "[:nick] gaf [:voices] voice á rásinni..." mostvoice2 = "[:nick] var líka mjög kurteis: [:voices] voice frá [:honum:henni:]." mostvoice3 = "Skrítið, engin voice voru gefin á [:channel]!" mostdevoice1 = "[:nick] hefur gaman af að devoicea, [:devoices] devoice." mostdevoice2 = "[:nick] hafði líka gaman af því, devoiceaði [:devoices] manns." mostdevoice3 = "Engin voice voru tekin á [:channel]!" action1 = "[:nick] lætur okkur alltaf vita hvað [:hann:hún:] er að gera: [:actions] lýsingar!" action2 = "[:nick] hefur líka mjög gaman af því, [:actions] lýsingar." action3 = "Engar lýsingar á [:channel]!" actiontext = "Til dæmis svona:
     [:line]" question1 = "Er [:nick] heimskur eða bara að spyrja of mikið? [:per]% lína innihéldu spurningu!" question2 = "[:nick] vissi ekki mikið heldur. [:per]% af [:hans:hennar:] línum voru spurningar." question3 = "Engin spurði spurninga hér, bara snillingar á þessari rás?" shout1 = "Sá hávaðasamasti var [:nick], sem öskraði [:per]% af tímanum!" shout2 = "Annar öskrari var [:nick], sem öskraði [:per]% af tímanum!" shout3 = "Enginn öskraði á rásinni" allcaps1 = "Það lítur út fyrir að shift-takkinn hjá [:nick] sé fastur: [:per]% af tímanum skrifaði [:hann:hún:] með HÁSTÖFUM." allcaps2 = "[:nick] gleymdi að taka Caps-Lock af hjá sér. [:Hann:Hún:] skrifaði með HÁSTÖFUM [:per]% af tímanum." allcaps3 = "Allir höfðu stjórn á shift takkanum sínum." allcapstext = "Til dæmis svona:
     [:line]" violent1 = "[:nick] er mjög árásargjarn. [:Hann:Hún:] réðst á aðra [:attacks] sinnum." violent2 = "[:nick] getur ekki stjórnað árásargirni sinni heldur. [:Hann:Hún:] réðst á aðra [:attacks] sinnum." violent3 = "Enginn réðst á neinn, allir voru vinir." violenttext = "Til dæmis svona:
     [:line]" attacked1 = "Aumingja [:nick], engum líkar við [:hann:hana:]. Ráðist var á [:Hann:Hana:] [:attacks] sinnum." attacked2 = "[:nick] lítur út fyrir að vera [:óvinsæll:óvinsæl:] líka. [:Hann:Hana:] var ráðist á [:attacks] sinnum." attackedtext = "Til dæmis svona:
     [:line]" gotkick1 = "[:nick] var ekki mjög [:vinsæll:vinsæl:], [:honum:henni:] var sparkað [:kicks] sinnum af rásinni!" gotkick2 = "[:nick] lítur út fyrir að vera hataður líka: [:Hann:Hún:] fékk [:kicks] spörk." kicktext = "Til dæmis svona:
     [:line]" joins = "[:nick] Gat ekki ákveðið hvort [:hann:hún:] ætti að koma eða fara. [:joins] innkomur á tímabilinu!" kick1 = "[:nick] er annað hvort [:geðveikur:geðveik:] eða sanngjarn op, sparkaði [:kicked] manns!" kick2 = "[:oldnick] á sér harðan fylgismann. [:nick] sparkar ekki jafn mörgum en sparkaði [:kicked] manns." kick3 = "Góðir opar hérna, engum var sparkað!" words1 = "[:nick] sagði í heildina [:words] orð!" words2 = "[:nick] reyndi mikið að tala jafn mikið og [:oldnick] en sagði einungis [:words] orð." words3 = "Enginn sagði neitt, skrítin rás" mono1 = "[:nick] talar mikið við [:sjálfan:sjálfa:] sig. [:Hann:Hún:] skrifaði meira en 5 línur í röð [:monos] sinnum!" mono2 = "Annar einmanna var [:nick], sem talaði við [:sjálfan:sjálfa:] sig [:monos] sinnum." wpl1 = "[:nick] skrifaði að meðaltali [:wpl] orð í hverri línu." wpl2 = "Meðaltalið rásarinnar var [:avg] orð í hverri línu." long1 = "[:nick] skrifaði lengstu línurnar, að meðaltali [:letters] stafi í hverri línu." long2 = "[:channel] meðaltalið var [:avg] stafir í hverri línu." short1 = "[:nick] skrifaði stystu línurnar, að meðaltali [:letters] stafi í hverri línu." short2 = "[:nick] var líka stuttorður, að meðaltali [:letters] stafir í hverri línu." foul1 = "[:nick] kunni öll dónalegu orðin. [:per]% af línum [:hans:hennar:] innihéldu dónaleg orð ." foul2 = "[:nick] kann líka fúkyrðin, [:per]% af línum [:hans:hennar:] innhéldu fúkyrði." foul3 = "Enginn hefur sagt eitthvað slæmt á [:channel]!" smiles1 = "[:nick] færir heiminum hamingju. [:per]% af línum [:hans:hennar:] innihéldu broskalla. :)" smiles2 = "[:nick] er heldur ekki fúll, brosandi [:per]% af tímanum." smiles3 = "Enginn brosir á [:channel]! Svona nú allir að fara að brosa." sad1 = "[:nick] virðist þjást af þunglyndi: [:per]% af línum [:hans:hennar:] innihéldu fýlukarla. :(" sad2 = "[:nick] er líka mjög leiður, fúll [:per]% af tímanum." sad3 = "Enginn er fýldur á [:channel]! En hvað þetta er glaðleg rás. :-)" month = "Janúar Febrúar Mars Apríl Maí Júní Júlí Ágúst September Október Nóvember Desember" +day = "sunnudaginn mánudaginn þriðjudaginn miðvikudaginn fimmtudaginn föstudaginn laugardaginn" ## Topics bignumtopic = "Stórar tölur" othernumtopic = "Aðrar áhugaverðar tölur" latesttopic = "Undanfarin umræðuefni" activetimestopic = "Virkasti tími sólarhringsins" activenickstopic = "Þessir tala mest" mostwordstopic = "Mest notuðu orðin" referencetopic = "Mest umtöluðu gælunöfnin" urlstopic = "Mest umræddu tenglarnir" notopic = "Umræðuefni hefur aldrei verið sett á rásinni" mostnickstopic = "Þeir með flestu gælunöfnin" bylinetopic = "[:date] eftir [:nick] klukkan [:time]" ## Other text totallines = "Fjöldi lína: [:lines]." totalnicks = "Það voru einnig [:totalnicks] aðrir sem sáust." totaltopic = "Umræðuefnið var sett [:total] sinnum." nick = "Gælunafn" names = "Nöfn notuð" url = "URL" numberlines = "Fjöldi lína" randquote = "Tilvitnun af handahófi" userpic = "Mynd" nottop = "Þessir komust ekki á toppinn:" word = "Orð" numberuses = "Fjöldi notkuna" show_words = "Fjöldi orða" show_time = "Hvenær?" show_wpl = "Orð í hverri línu" show_cpl = "Stafir í hverri línu" show_lastseen = "Síðast séður" lastused = "Síðast notað af" lastseen1 = "[:days] degi síðan" lastseen2 = "[:days] dögum síðan" today = "Í dag" pagetitle1 = "[:channel] @ [:network] tölfræði frá [:maintainer]" pagetitle2 = "Tölfræði búin til" pagetitle3 = "Á þessu [:days] daga tímabili, sáust [:nicks] mismunandi gælunöfn á [:channel]." stats_gen_by = "Tölfræði búin til af [:pisg_url] v[:version]" author = "pisg er skrifað af [:author_url] og öðrum" stats_gen_in = "Tölfræði búin til á [:time]" hours = "klukkustundum" minutes = "mínútum" seconds = "sekúndum" and = "og" # Mouse-over titles pisghomepage = "Fara á heimasíðu pisg" authorhomepage = "Fara á heimasíðu höfundar" newwindow = "Opna nýjan glugga:" mailto = "Senda tölvupóst til"
### Czech mostop1 = "[:nick] dal [:ops] opù na kanále..." mostop2 = "[:nick] byl také velice pozorný. Rozdal [:ops]x op." mostop3 = "Divné, nikdo nebyl opnut na [:channel]!" mostdeop1 = "[:nick] bránil kanál [:deops] deopnutími." mostdeop2 = "[:nick] deopnul [:deops] uživatelù." mostdeop3 = "Wow, nikomu nebyl na [:channel] odebran op!" mosthalfop1 = "[:nick] daroval [:halfops] halfopù na kanále…" mosthalfop2 = "[:nick] byl také velmi slušný: [:halfops] halfopù od [:him:her:]." mosthalfop3 = "Zvláštní, žádní halfopové nebyly dáni na kanálu [:channel]!" mostdehalfop1 = "[:nick] je kanálový šerif s [:dehalfops] dehalfops." mostdehalfop2 = "[:nick] odejmul halfopa [:dehalfops] uživatelùm." mostdehalfop3 = "Wow, žádný halfop nebyl odejmut na [:channel]!" mostvoice1 = "[:nick] dal [:voices]x voice na kanale..." mostvoice2 = "[:nick] byl také docela pozorný. Udìlil [:voices]x voice." mostvoice3 = "Hmm divné, žádný voice nebyl na [:channel] udìlen!" mostdevoice1 = "[:nick] rád bere lidem voice, [:devoices]x devoice." mostdevoice2 = "[:nick] je starej despota, sebral voice [:devoices]ti uživatelùm." mostdevoice3 = "Žádný voice nebyl odebrán na kanale [:channel]!" action1 = "[:nick] na sebe vždy práskne co dìlá. [:actions] akcí!" action2 = "Také, [:nick] dává na jevo svou èinnost [:actions] akcema." action3 = "Žádné akce na [:channel]!" actiontext = "Jako tohle: [:line]" question1 = "Je [:nick] hloupý(á), nebo má jen tolik dotazù? [:per]% lajn obsahuje otázku!" question2 = "[:nick] na tom je podobnì, moc toho neví. [:per]% z nakecaného obsahuje otázku." question3 = "Nikdo se tu na nic neptá; samí geniové ?" shout1 = "Nejhlasitejsi byl [:nick], kterej tady zdùrazòoval [:per]% svého casu!" shout2 = "Jiná stará mluvka byl [:nick], kterej tu zdùrazòoval [:per]% své konverzace!" shout3 = "Nikdo tu na ! ani nešáhl, wow." allcaps1 = "Vypadá to, že [:nick] držel svuj SHIFT [:per]% celeho èasu co psal(a)." allcaps2 = "[:nick] pravì zapomel vypnout svùj Caps-Lock. [:Napsal:a:] VELKÝM [:per]% of the time." allcaps3 = "Každej mìl svùj shift-key pod kontrolou. :)" allcapstext = "Napriklad: [:line]" violent1 = "[:nick] je velmi agresivni osoba. Napadl(a) [:attacks]x ostatní." violent2 = "[:nick] neovládá svou agresi. Napadl(a) ostatní [:attacks]x ." violent3 = "Tady se teda maj radi, po nikom se tu nevozí :)." violenttext = "Jako tohle: [:line]" attacked1 = "Chudáèek [:nick], nikdo ho nemá rád. Byl(a) napaden(a) [:attacks]x ." attacked2 = "[:nick] vypadá, že také není moc oblíbený(a). Napadli [:ji:ho:] [:attacks]x ." attackedtext = "Jako tohle: [:line]" gotkick1 = "[:nick] není moc populární, Kopli jste ho [:kicks]x !" gotkick2 = "[:nick] vypadá jako by jste ho taky nemìli rádi. Dostal [:kicks]x ." kicktext = "Jako tohle: [:line]" joins = "[:nick] ukazoval jak mu to padá (žabièka). Joinul se [:joins]x !" kick1 = "[:nick] je asi pomatenej, nebo je jen spravedlivejší op. Vyhodil celkem [:kicked] lidí!" kick2 = "[:oldnick] má zdatného následovnika, a je to [:nick], kterej vykopl [:kicked] lidi." kick3 = "Jsou tady nìjak mìccí opi, nikoho nekopli!" words1 = "[:nick] promluvil(a) celkem [:words] slov!" words2 = "[:oldnick] má zdatného následovnika, a je to [:nick], promluvil jen: [:words] slov." words3 = "Nikdo tady nemluvi ... Nìjakej divnej kanál..." mono1 = "[:nick] mluvil pro sebe víc než je zdrávo. Hodil(a) sem po sobì 5 lajn a to [:monos]x po sobì !" mono2 = "Další osamìlec je [:nick], kterej to zvádl jen [:monos]x." wpl1 = "[:nick] napsal prùmìrnì [:wpl] slov na lajnu." wpl2 = "Kanálový prùmìr je [:avg] slov na lajnu." long1 = "[:nick] napsal nejdelší lajnu, prùmìrnì [:letters] znakù." long2 = "[:channel] prùmìr byl [:avg] znakù na lajnu." short1 = "[:nick] napsal nejkratsi lajnu, prùmìrnì [:letters] písmen." short2 = "[:nick] taky èasto maèkal "enter", prùmìrnì napsal [:letters] znakù." foul1 = "[:nick] byl(a) celkem neslušný(á). [:per]% toho co zplodil(a) obsahuje nadávky." foul2 = "[:nick] by se mìl stydìt za [:per]% ze zaznamenaného cyklu." foul3 = "Nikdo si neoteviral usta na [:channel]! Není to moc?" smiles1 = "[:nick] je šastnej jako blecha. [:per]% z toho co napsal obsahuje úsmìv. :)" smiles2 = "[:nick] nemùže být smutná osoba, smìje se [:per]% zaznamenaného cyklu." smiles3 = "Nikdo se na [:channel] nesmìje! Chtìlo by to tu trošku rozjet." sad1 = "[:nick] nevypadá zrovna šastnì. [:per]% z toho co napsal(a) obsahuje smutný oblièej. :(" sad2 = "[:nick] je taky nešastná osoba, pláèe [:per]% zaznamenaného cyklu." sad3 = "Všeci jsou na [:channel] vysmatí! Usmìj se taky. :-)" month = "Ledena Února Bøezna Dubna Kvìtena Èervna Èervence Srpna Záøí Øíjna Listopadu Prosince" day = "Pondelí Uterý Støedu Ètvrtek Pátek Sobotu Nedìli" ## Topics bignumtopic = "Velká èísla" othernumtopic = "Další zajímavá èísla" latesttopic = "Poslení Topic" activetimestopic = "Zatížení kanálu" activenickstopic = "Nejvíc užvanìní" mostwordstopic = "Nejpoužívanìjší slova" referencetopic = "Nejpoužívanìjší Nicky" urlstopic = "Nejpoužívanìjší odkazy" notopic = "Topic na tomto kanále nebyl ještì zadán." mostnickstopic = "Uživatelé s více nicky" bylinetopic = "[:date] podle [:nick] na [:time]" chartstopic = "[:channel] Hudební hitparáda" smileytopic = "Smajlíci :-) " dailyactivitytopic = "Denní aktivita (posledních [:n] dnù" activegenderstopic = "Nejvíce aktivní pohlaví" activenickbyhourtopic = "Nejvíce aktivní nicky podle hodin" karmatopic = "[:channel] karma" ## Other text totallines = "Koneèný poèet stav. [:lines] lajn." totalnicks = "By the way, bylo zde [:totalnicks] jiných nicku." totaltopic = "Topic zmìnili celkem [:total]x." nick = "Nick" names = "Jméno" url = "Odkaz" numberlines = "poèet lajn" randquote = "Náhodná vìta" userpic = "Obrázek" nottop = "Tihle nebyli dost ukecaní:" word = "Slovo" numberuses = "Poèet použití" show_words = "Poèet slov" show_time = "Kdy?" show_wpl = "Slovo na Lajnu" show_cpl = "Znaku na Lajnu" show_lastseen = "Naposledy viïen" lastused = "Naposledy použil" lastseen1 = "[:days] vèera" lastseen2 = "[:days] days ago" today = "dnes" pagetitle1 = "Malá statistika z [:channel] @ [:network] od [:maintainer]" pagetitle2 = "Statistiky vygenerovány v " pagetitle3 = "Bìhem tohoto [:days]-denního zaznamenaného cyklu, zde([:channel]) bylo celkem [:nicks] rùzných lidí." stats_gen_by = "Stats generated by [:pisg_url] v[:version]" author = "pisg by [:author_url] and translate by James (ø)" stats_gen_in = "Stats generated in [:time]" hours = "hodiny" minutes = "minuty" seconds = "sekundy" and = "a" names1 = "Jména" names2 = "Jméno" karma = "Karma" badkarma = "Zlá karma od" goodkarma = "Dobrá karma od" smiley = "Smajlíci" foultext = "Napøíklad, jako toto: [:line]" gender = "Pohlaví" gender_b = "Bot" gender_f = "Žena" gender_m = "Muž" song = "Písen" playedby = "Naposledny hrál" numberplayed = "Jak èasto pøehráváno" # Mouse-over titles pisghomepage = "Go to the pisg homepage" authorhomepage = "Go to the authors homepage" newwindow = "Open in new window:" mailto = "Mail to" ### Slovak mostop1 = "[:nick] @[:ol:la:] [:ops]x ." mostop2 = "[:nick] bol[::a:] tiež ve¾mi zdvoril[:ý:á:]. Rozdal[::a:] @ [:ops]x ." mostop3 = "Zaujímavé, nikto nebol opnutý na [:channel] :)" mostdeop1 = "[:nick] bránil[::a:] kanál [:deops] deopmi." mostdeop2 = "[:nick] deop[:ol:la:] [:deops] užívate¾ov." mostdeop3 = "Wow, nikmu nebol odobraný op na [:channel]!" mosthalfop1 = "[:nick] daroval [:halfops] halfop-ov na kanali..." mosthalfop2 = "[:nick] bol tiež ve¾mi slušný: [:halfops] halfop-y od [:him:her:]." mosthalfop3 = "Divné, žiadny halfop nebol daný na [:channel]!" mostdehalfop1 = "[:nick] je kanálový šerif s [:dehalfops] dehalfop-mi." mostdehalfop2 = "[:nick] dehalfop-nutých [:dehalfops] používate¾ov." mostdehalfop3 = "Wau, žiadny halfop nebol zobraný na [:channel]!" mostvoice1 = "[:nick] dal[::a:] [:voices] hlas(ov) na kanale..." mostvoice2 = "[:nick] bol[::a:] tiež ve¾mi zdvoril[:ý:á:]. Rozdal[::a:] [:voices] hlas(ov)." mostvoice3 = " Zaujímavé, hlas nebol dany nikomu na [:channel]!" mostdevoice1 = "[:nick] [:rád:rada:] berie ¾uïom hlas, celkom: [:devoices]x." mostdevoice2 = "[:nick] sa k tomu priblížil[::a:]. Odobral[::a:] hlas [:devoices] užívate¾om." mostdevoice3 = "Žiadny hlas nebol odobraný na kanále [:channel]!" action1 = "[:nick] nám [:rád:rada:] hovorí èo robí: [:actions] akcií!" action2 = "[:nick] tiež èasto hovorí èo robí, so svojimi [:actions] akciami." action3 = "Žiadne akcie na kanále [:channel]!" actiontext = "Napríklad:     [:line]" question1 = "Je [:nick] hlupá[:k:èka:], alebo sa len prive¾a pýta? [:per]% riadkov obsahuje otázku!" question2 = "[:nick] je na tom podobne, ve¾a toho nevie. [:per]% z [:jeho:jej:] viet obsahuje otázku." question3 = "Nikdo se tu na niè nepýta, samí géniovia ?" shout1 = "Najhluènejš[:í:ia:] bol[::a:] [:nick], ktor[:ý:á:] tu vrieskal[::a:] [:per]% èasu!" shout2 = "Druh[:ý:á:] najstarš[:í:ia:] krik¾úò[::ka:] bol[::a:] [:nick] s [:per]%!" shout3 = "Nikdo tu nekrièal, wow :)." allcaps1 = "Vyzerá, že [:nick] mal[::a:] stlaèený CAPS LOCK [:per]% èasu." allcaps2 = "[:nick] tiež zabud[:ol:la:] vypnú svoj Caps-Lock. Písal[::a:] VELKÝM [:per]% èasu." allcaps3 = "Všetci mali svoj shift pod kontrolou. :)" allcapstext = "Napríklad:     [:line]" violent1 = "[:nick] je ve¾mi agresívna osoba. Zaútoèil[::a:] [:attacks]x na ostatných." violent2 = "[:nick] tiež neovláda svoju agresiu. Napad[:ol:la:] ostatných [:attacks]x ." violent3 = "Tu sa teda majú radi :)." violenttext = "Napríklad, ako toto:     [:line]" attacked1 = "Chudinka [:nick], nikdo [:ho:ju:] nemá rád. Bol[::a:] napadnut[:ý:á:] [:attacks]x ." attacked2 = "[:nick] vyzerá, že tiež nie je ve¾mi ob¾úben[:ý:á:]. Napadli [:ho:ju:] [:attacks]x ." attackedtext = "Napríklad, takto:     [:line]" gotkick1 = "[:nick] nie je ve¾mi populárn[:y:a:]. Bol[::a:] vykopnut[:ý:á:] [:kicks]x !" gotkick2 = "[:nick] vyzerá ako by [:ho:ju:] tiež nemali radi. Dostal kick [:kicks]x ." kicktext = "Napríklad takto:     [:line]" joins = "[:nick] je dos nerozhodn[:ý:á:]. Prišiel[::a:] na kanál [:joins]x !" kick1 = "[:nick] je trošku vystresovan[:ý:á:], alebo len ve¾mi spravodliv[:ý:á:] op. Vyhodil[::a:] celkom [:kicked] ¾udí!" kick2 = "[:nick] je vern[:ý:á:] následovní[:k:èka:]. Vykop[:ol:la:] [:kicked] ¾udí." kick3 = "Sú tu samé lemry, nikoho nekopli !" words1 = "[:nick] napísal[::a:] celkom [:words] slov!" words2 = "[:nick] sa to snaží dohna s [:words] slovami." words3 = "Nikto tu niè nepíše ... divný kanál..." mono1 = "[:nick] sa èasto rozpráva [:sám:sama:] so sebou. Napísal[::a:] 5+ riadkov po sebe [:monos]x!" mono2 = "Ïa¾šia osamelá duša je [:nick], ktorém[:u:ej:] sa to stalo [:monos]x." wpl1 = "[:nick] napísal[::a:] priemerne [:wpl] slov na riadok." wpl2 = "Priemer kanála je [:avg] slov na riadok." long1 = "[:nick] píše najdlhšie riadky. Priemerne [:letters] znakov na riadok." long2 = "priemer [:channel] je [:avg] znakov na riadok." short1 = "[:nick] píše najkratšie riadky. Priemerne [:letters] znakov na riadok." short2 = "[:nick] je tiež skúp[:y:a:] na slovo. Priemerne napísal[::a:] [:letters] znakov na riadok." foul1 = "Štatistiku nevymáchaných húb vedie [:nick]. [:per]% nadávok na riadok." foul2 = "[:nick] ma tiež celkom drsný slovník. [:per]% zo zaznamenaného cyklu." foul3 = "Nikdo si neotváral ústa na [:channel]? Nepreháòajte to!" smiles1 = "[:nick] prináša rados do života. [:per]% riadkov obsahuje smajlík :)" smiles2 = "[:nick] tiež nemôže by smutn[:ý:á:]. Usmieva sa v [:per]% riadkov." smiles3 = "Nikto se na [:channel] nesmeje! Sýýýýýýýýr! :)" sad1 = "[:nick] vyzerá nešastne: [:per]% riadkov obsahuje smutný xixtiq :(" sad2 = "[:nick] je tiež nešastná osoba, preplaèe [:per]% èasu." sad3 = "Nikto nieje nešastný na [:channel]! Hmm... " month = "januára februára marca apríla mája júna júla augusta septembra októbra novembra decembra" day = "Nede¾u Pondelok Utorok Stredu Štvrtok Piatok Sobotu" ## Topics bignumtopic = "Ve¾ké èísla" othernumtopic = "Dalšie zaujímavé èísla" latesttopic = "Poslený Topic" activetimestopic = "Zaaženie kanála" activenickstopic = "Nejukecanejší" mostwordstopic = "Najpoužívanejšie slová" referencetopic = "Najpoužívanejšie prezývky" urlstopic = "Najpoužívanejšie odkazy" notopic = "Topic na tomto kanále ešte nebol nastavený." mostnickstopic = "Užívatelia s viacerými prezývkami" bylinetopic = "[:date] nastavil [:nick] [:time]" smileytopic = "Smajlíci :-)" chartstopic = "[:channel] Hudobné rebríèky" karmatopic = "[:channel] karma" activenickbyhourtopic = "Najaktívnejšie prezývky pod¾a hodín" dailyactivitytopic = "Denná aktivita (last [:n] dní)" activegenderstopic = "Najaktívnejšie pohlavie" ## Other text totallines = "Celkový poèet riadkov: [:lines]." totalnicks = "Ale bolo tu aj [:totalnicks] iných prezývok." totaltopic = "Topic sa menil celkom [:total]x." nick = "Prezývka" names = "Meno" url = "Odkaz" numberlines = "Poèet riadkov" randquote = "Náhodná veta" userpic = "Obrázok" nottop = "Títo neboli dos ukecaní:" word = "Slovo" numberuses = "Poèet použití" show_words = "Poèet slov" show_time = "Kedy" show_wpl = "Slov na riadok" show_cpl = "Znakov na riadok" show_lastseen = "Naposledy videný" lastused = "Naposledy použil(a)" lastseen1 = "[:days] deò dozadu" lastseen2 = "[:days] dni dozadu" today = "dnes" pagetitle1 = "Malá štatistika z [:channel] @ [:network] od bota [:maintainer]" pagetitle2 = "Štatistika vygenerovaná v " pagetitle3 = "Poèas týchto [:days] dní, bolo na [:channel] celkom [:nicks] rozdielnych prezývok." stats_gen_by = "Štatistiky generované programom [:pisg_url] v[:version]" author = "Pisg napísal [:author_url], preložil Snowman a gramatyku opravovala janula :)" stats_gen_in = "Štatistiky sa generovali [:time]" hours = "hod." minutes = "min." seconds = "sek." and = "a" names1 = "Mená" names2 = "Meno" karma = "Karma" badkarma = "Zlá karma od" goodkarma = "Dobrá karma od" smiley = "Smajlík" foultext = "Napríklad, ako toto:
     [:line]" gender = "Pohlavie" gender_f = "Žena" gender_m = "Muž" gender_b = "Bot" song = "Pieseò" numberplayed = "Ako èasto hraná" playedby = "Naposledy hraná od" # Mouse-over titles pisghomepage = "Choï na domácu stránku programu pisg" authorhomepage = "Choï na autorovu domácu stránku" newwindow = "Otvor v novom okne:" mailto = "Pošli mail pre"
### Russian mostop1 = "[:nick] ðàçäàë [:ops] îïîâ íà êàíàëå..." mostop2 = "[:nick] òîæå î÷åíü äîáð: [:ops] îïîâ." mostop3 = "Ñòðàííî, íèêòî îïà íå äàâàë íà [:channel]!" mostdeop1 = "[:nick] - øåðèô êàíàëà ñ [:deops] äåîïàìè." mostdeop2 = "[:nick] îòíÿë îïà ó [:deops] þçåðîâ." mostdeop3 = "Âàó, íè ó êîãî îïà íå îòáèðàëè íà [:channel]!" mosthalfop1 = "[:nick] ñäåëàë [:halfops] ïîëó-îïåðàòîðàìè..." mosthalfop2 = "[:nick] was also very polite: [:halfops] halfops from [:him:her:]." mosthalfop3 = "Ñòðàííî, íè îäíîãî ïîëó-îïåðàòîðà íà [:channel]!" mostdehalfop1 = "[:nick] øåðèôô êàíàëà äëÿ [:dehalfops] ïîëó-îïåðàòîðîâ." mostdehalfop2 = "[:nick] ñíÿë ñòàòóñ ïîëó-îïåðàòîðà ñ [:dehalfops] þçåðîâ." mostdehalfop3 = "Óõõ, íè ó êîãî íå çàáðàëè ïðàâà ïîëó-îïåðàòîðà íà [:channel]!" mostvoice1 = "[:nick] ðàçäàë [:voices] âîéñîâ íà êàíàëå..." mostvoice2 = "[:nick] òîæå î÷åíü äîáð: [:voices] âîéñîâ." mostvoice3 = "Ñòðàííî, íè îäíîãî âîéñà íà [:channel]!" mostdevoice1 = "[:nick] ëþáèò îòáèðàòü âîéñû ó ëþäåé - [:devoices] äåâîéñîâ." mostdevoice2 = "[:nick] òîæå æàäåí, äåâîéñíóë [:devoices] þçåðîâ." mostdevoice3 = "Íè ó êîãî íå îòáèðàëè âîéñû íà [:channel]!" action1 = "[:nick] âñåãäà äà¸ò íàì çíàòü, ÷òî äåëàåò: [:actions]!" action2 = "Òàêæå, [:nick] ãîâîðèò íàì, ÷òî äåëàåò - [:actions]." action3 = "Íè÷åãî íèêòî íå äåëàåò íà [:channel]!" actiontext = "Íàïðèìåð, âîò òàê:
     [:line]" question1 = "[:nick] ãëóï èëè ïðîñòî çàäà¸ò ñëèøêîì ìíîãî âîïðîñîâ? [:per]% åãî (å¸) ñòðîê ñîäåðæàëè âîïðîñ!" question2 = "[:nick] íå íàìíîãî óìíåå. [:per]% åãî(å¸) ñòðîê áûëè âîïðîñèòåëüíûìè." question3 = "Íèêòî íå çàäàâàë çäåñü âîïðîñîâ; îäíè ãåíèè íà êàíàëå, ÷òî ëè?" shout1 = "Ñàìûì ãðîìêèì áûë [:nick], êîòîðûé(àÿ) âîïèë(à) [:per]% âðåìåíè, ïðîâåä¸ííîãî íà êàíàëå!" shout2 = "Åù¸ îäíèì ñòàðûì êðèêóíîì áûë [:nick], - êðè÷àë [:per]% âðåìåíè!" shout3 = "Âàó, íèêòî òóò íå îðàë ñîâñåì." allcaps1 = "Ïîõîæå, êëàâèøà Shift ó [:nick]çàïàëà: [:per]% âðåìåíè îí(à) ïèñàë(à) ÁÎËÜØÈÌÈ ÁÓÊÂÀÌÈ." allcaps2 = "[:nick] ïðîñòî çàáûë(à) îòêëþ÷èòü ñâîé Caps-Lock. Ïèñàë(à) ÁÎËÜØÈÌÈ ÁÓÊÂÀÌÈ [:per]% âðåìåíè." allcaps3 = "Ó âñåõ êëàâèøà Shift áûëà ïîä êîíòðîëåì. :)" allcapstext = "Íàïðèìåð, âîò òàê:
     [:line]" violent1 = "[:nick] î÷åíü àãðåññèâíàÿ ëè÷íîñòü. Îí(à) àòàêîâàë(à) äðóãèõ [:attacks] ðàç." violent2 = "[:nick] òîæå íå ìîæåò êîíòðîëèðîâàòü ñâîþ àãðåññèþ. Íàåçæàë(à) íà äðóãèõ [:attacks] ðàç." violent3 = "Íèêòî íå íàåçæàåò, âñå âåäóò ñåáÿ äðóæåñòâåííî." violenttext = "Íàïðèìåð, âîò òàê:
     [:line]" attacked1 = "Áåäíûé(àÿ) [:nick], íèêòî åãî(å¸) íå ëþáèò. Åãî/å¸ àòàêîâàëè [:attacks] ðàç." attacked2 = "[:nick] òîæå ïîõîæå íå ëþáÿò. Áèëè [:attacks] ðàç." attackedtext = "Íàïðèìåð, âîò òàê:
     [:line]" gotkick1 = "[:nick] íå î÷åíü ïîïóëÿðåí(íà) - êèêíóëè [:kicks] ðàç!" gotkick2 = "[:nick] âèäèìî òîæå íåíàâèäÿò: [:kicks] ïîëó÷èë(à)." kicktext = "Íàïðèìåð, âîò òàê:
     [:line]" joins = "[:nick] íå ìîã(ëà) ïðèíÿòü ðåøåíèå - îñòàòüñÿ èëè óéòè. [:joins] âõîäîâ íà êàíàë çà îò÷¸òíûé ïåðèîä!" kick1 = "[:nick] ëèáî ñîø¸ë ñ óìà, ëèáî ïðîñòî ÷åñòíûé îï - êèêíóë âñåãî [:kicked] þçåðîâ!" kick2 = "Âåðíûé ïîñëåäîâàòåëü [:oldnick], [:nick], êèêíóë [:kicked] þçåðîâ." kick3 = "Õîðîøèå îïû çäåñü - íèêîãî íå êèêàëè!" words1 = "[:nick] ïðîèçí¸ñ âñåãî [:words] ñëîâ!" words2 = "Âåðíûé äðóã è ñîðàòíèê [:oldnick], [:nick], ãîâîðèë íå òàê ìíîãî: [:words] ñëîâ." words3 = "Íèêòî íè÷åãî íå ãîâîðèë... ×òî çà ñòðàííûé êàíàë..." mono1 = "[:nick] ìíîãî ðàçãîâàðèâàåò ñ ñîáîé. Ïèñàë(à) áîëåå 5 ñòðîê ïîäðÿä [:monos] ðàç!" mono2 = "Åù¸ îäíà îäèíîêàÿ îñîáà - [:nick], ãîâîðèâøèé(àÿ) ñàì(à) ñ ñîáîé [:monos] ðàç." wpl1 = "[:nick] ïèñàë(à) â ñðåäíåì [:wpl] ñëîâ â ñòðîêå." wpl2 = "Ñðåäíåå ïî êàíàëó êîëè÷åñòâî ñëîâ â ñòðîêå - [:avg]." long1 = "[:nick] ïèñàë(à) ñàìûå äëèííûå ñòðîêè, â ñðåäíåì ïî [:letters] áóêâ â ñòðîêå." long2 = "[:channel] Ñðåäíåå êîëè÷åñòâî áóêâ â ñòðîêå ïî êàíàëó - [:avg]." short1 = "[:nick] ïèñàë(à) êðàò÷àéøèå ñòðîêè, â ñðåäíåì [:letters] ñèìâîëîâ â ñòðîêå." short2 = "[:nick] òîæå êðàòîê, â ñðåäíåì [:letters] ñèìâîëîâ." foul1 = "[:nick] ÷àñòî ñêâåðíîñëîâèò. [:per]% ñòðîê ñîäåðæàò áðàíü." foul2 = "[:nick] òàêæå âãîíÿåò ìàòðîñîâ â êðàñêó, [:per]% âðåìåíè." foul3 = "Íèêòî íå áðàíèòñÿ íà [:channel]! Äà íó âàñ!?" smiles1 = "[:nick] íåñ¸ò ìèðó ñ÷àñòüå. [:per]% ñòðîê ñîäåðæàëè óëûáêó. :)" smiles2 = "[:nick] òîæå íå ïå÷àëèòñÿ - óëûáàåòñÿ [:per]% âðåìåíè." smiles3 = "Íåò óëûáîê íà [:channel]! Íå óíûâàéòå, äåâî÷êè è ìàëü÷èêè." sad1 = "[:nick] êàæèñü, ïå÷àëèòñÿ: [:per]% ñòðîê âûðàæàþò ïå÷àëü. :(" sad2 = "Åù¸ îäíà ïå÷àëüíàÿ ïåðñîíà - [:nick], ïëà÷åò [:per]% âðåìåíè." sad3 = "Íåò ïå÷àëè íà [:channel]! Êàêîé ñ÷àñòëèâûé êàíàë. :-)" month = "ßíâàðü Ôåâðàëü Ìàðò Àïðåëü Ìàé Èþíü Èþëü Àâãóñò Ñåíòÿáðü Îêòÿáðü Íîÿáðü Äåêàáðü" day = "Âîñêðåñåíüå Ïîíåäåëüíèê Âòîðíèê Ñðåäà ×åòâåðã Ïÿòíèöà Ñóááîòà " ## Topics bignumtopic = "Áîëüøèå öèôðû" othernumtopic = "Äðóãèå èíòåðåñíûå öèôðû" latesttopic = "Ïîñëåäíèå òîïèêè" activetimestopic = "Êîãäà ìû òóò ÷àùå áîëòàåì" activenickstopic = "Ñàìûå àêòèâíûå ïîëüçîâàòåëè" activenickbyhourtopic = "Ñàìûå àêòèâíûå ïîëüçîâàòåëè ïî ÷àñàì" mostwordstopic = "Íàèáîëåå ÷àñòî èñïîëüçóåìûå ñëîâà" referencetopic = "Íàèáîëåå ïîïóëÿðíûé íèê" urlstopic = "Íàèáîëåå ïîïóëÿðíûé URL" notopic = "Íà ýòîì êàíàëå íèêîãäà íå áûëî òîïèêà." mostnickstopic = "Ïîëüçîâàòåëè ñ íàèáîëüøèì êîëè÷åñòâîì íèêîâ" bylinetopic = "[:date] Àâòîð - [:nick] îò [:time]" dailyactivitytopic = "Àêòèâíîñòü çà äåíü (çà ïîñëåäíèå [:n] äíåé)" smileytopic = "Smileys :-)" chartstopic = "[:channel] Ìóçûêàëüíûé ×àðò" karmatopic = "[:channel] êàðìà" activegenderstopic = "Ñàìûå àêòèâíûå òåìû" ## Other text totallines = "Îáùåå êîëè÷åñòâî ñòðîê: [:lines]." totalnicks = "Êñòàòè, åù¸ áûëî [:totalnicks] äðóãèõ íèêîâ." totaltopic = "Òîïèê óñòàíàâëèâàëñÿ [:total] ðàç." nick = "Íèê" names = "Èñïîëüçóåìûå èìåíà" url = "URL" numberlines = "Êîëè÷åñòâî ñòðîê" randquote = "Ñëó÷àéíàÿ ôðàçà" userpic = "Ôîòî þçåðà" nottop = "Ýòè íå ïîïàëè â òîï:" word = "Ñëîâî" numberuses = "Êîëè÷åñòâî èñïîëüçîâàíèé" show_words = "Êîëè÷åñòâî ñëîâ" show_time = "Êîãäà?" show_wpl = "Ñëîâ â ñòðîêå" show_cpl = "Ñèìâîëîâ â ñòðîêå" show_lastseen = "Ïîñëåäíèé ðàç âèäåëè" lastused = "Ïîñëåäíèé ðàç èñïîëüçîâàëñÿ" lastseen1 = "[:days] äíåé íàçàä" lastseen2 = "[:days] äíåé íàçàä" today = "ñåãîäíÿ" pagetitle1 = "Ñòàòèñòèêà [:channel] @ [:network] [:maintainer]" pagetitle2 = "Ñòàòèñòèêà ñãåíåðèðîâàíà " pagetitle3 = "Çà ýòîò [:days]-äíåâíûé îò÷¸òíûé ïåðèîä, âñåãî [:nicks] ðàçëè÷íûõ íèêîâ áûëî ïðåäñòàâëåíî íà [:channel]." stats_gen_by = "Ñòàòèñòèêà ñãåíåððèðîâàíà [:pisg_url] v[:version]" author = "pisg by [:author_url] è äðóãèå. Ïåðåâîä HUGO" stats_gen_in = "Ñòàòèñòèêà ñãåíåðèðîâàíà çà [:time]" hours = "÷àñîâ" minutes = "ìèíóò" seconds = "ñåêóíä" and = "è" names1 = "èìåíà" names2 = "èìÿ" karma = "Êàðìà" badkarma = "Ïëîõàÿ êàðìà" goodkarma = "Õîðîøàÿ êàðìà" smiley = "Smiley" foultext = "Íàïðèìåð âîò òàê:
     [:line]" gender = "Ïîë" gender_b = "Bot" gender_f = "Æåíñêèé" gender_m = "Ìóæñêîé" song = "Ïåñíÿ" playedby = "Ïðîñëóøàë ïîñëåäíèé ðàç" numberplayed = "Ñêîëüêî ðàç ïðîñëóøàíî" # Mouse-over titles pisghomepage = "Ïîñåòèòü äîìàøíþþ ñòðàíèöó pisg" authorhomepage = "Ïîñåòèòü äîìàøíþþ ñòðàíèöó àâòîðîâ" newwindow = "Îòêðûòü â íîâîì îêíå:" mailto = "Ìûëüíóòü"
### Greek mostop1 = "Ï/ç [:nick] Ýäùóå [:ops] ops óôï êáíÜëé..." mostop2 = "Ï/ç [:nick] áêïëïýèçóå åõãåíéêÜ ìå [:ops]." mostop3 = "Ðåñßåñãï, êáíÝíá op äåí äþèçêå óôï [:channel]!" mostdeop1 = "Ï/ç [:nick] åßíáé ï óåñßöçò ôïõ êáíáëéïý ìå [:deops] deops." mostdeop2 = "Åðßóçò ï/ç [:nick] Ýêáíå deop óå [:deops] ÷ñÞóôåò." mostdeop3 = "Öïâåñü, êáíÝíá op äåí áöáéñÝèçêå óôï [:channel]!" mostvoice1 = "Ï/ç [:nick] Ýäùóå [:voices] voices óôï êáíÜëé..." mostvoice2 = "Ï/ç [:nick] áêïëïýèçóå åõãåíéêÜ ìå [:voices]." mostvoice3 = "Ðåñßåñãï, êáíÝíá voice äåí äþèçêå óôï [:channel]!" mostdevoice1 = "Ï/ç [:nick] áñÝóêåôáé óôï íá áöáéñåß ôá voices ôïõ êüóìïõ. ¸êáíå devoice [:devoices] öïñÝò." mostdevoice2 = "Ï/ç [:nick] äåí ðÞãå ðßóù, Ýêáíå devoice óå [:devoices] ÷ñÞóôåò." mostdevoice3 = "ÊáíÝíá devoice äåí Ýãéíå óôï [:channel]!" mosthalfop1 = "Ï/ç [:nick] Ýäùóå [:halfops] halfops óôï êáíÜëé." mosthalfop2 = "Ï/ç [:nick] áêïëïýèçóå åõãåíéêÜ ìå [:halfops] halfops." mosthalfop3 = "Ðåñßåñãï, êáíÝíá halfop äåí äþèçêå óôï [:channel]!" mostdehalfop1 = "Ï/ç [:nick] åßíáé ï óåñßöçò ôïõ êáíáëéïý ìå [:dehalfops] dehalfops." mostdehalfop2 = "Ï/ç [:nick] Ýêáíå dehalfop óå [:dehalfops] ÷ñÞóôåò." mostdehalfop3 = "Öïâåñü, êáíÝíá halfop äåí áöáéñÝèçêå óôï [:channel]!" action1 = "Ï/ç [:nick] ìáò åíçìåñþíåé äéáñêþò ãéá ôï ôé êÜíåé: [:actions] actions!" action2 = "Åðßóçò ï/ç [:nick] ìáò ëÝåé ôé ôñÝ÷åé ìå [:actions]." action3 = "ÊáíÝíá action óôï [:channel]!" actiontext = "Ãéá ðáñÜäåéãìá:
     [:line]" question1 = "[:nick]: áíïçóßá Þ áðëþò ðïëëÝò áðïñßåò; Ôï [:per]% ôùí ãñáììþí ðåñéåß÷áí åñþôçóç!" question2 = "Åðßóçò ï/ç [:nick] äåí öáßíåôáé íá ãíùñßæåé êáé ðÜñá ðïëëÜ ìå [:per]% åñùôÞóåùí." question3 = "Êáíåßò äåí êÜíåé åñùôÞóåéò åäþ. ÌÞðùò üëïé åßíáé éäéïöõßåò;" shout1 = "Ï/ç [:nick] ÷ñçóéìïðïßçóå èáõìáóôéêÜ óå ðïóïóôü [:per]%!" shout2 = "Ï/ç [:nick] áêïëïýèçóå ìå [:per]%." shout3 = "Óå áõôü ôï êáíÜëé, äåí ÷ñçóéìïðïéåß êáíåßò èáõìáóôéêÜ!" allcaps1 = "Öáßíåôáé üôé ï/ç [:nick] Ý÷åé ìïíßìùò ðáôçìÝíï ôï Caps Lock: [:per]% ÷ñÞóç ÊÅÖÁËÁÉÙÍ." allcaps2 = "ÁëëÜ êáé ï/ç [:nick] ìÜëëïí îÝ÷áóå íá ôï áðåíåñãïðïéÞóåé. [:per]% ÷ñÞóç ÊÅÖÁËÁÉÙÍ." allcaps3 = "Åõôõ÷þò óå áõôü ôï êáíÜëé, äåí öùíÜæåé êáíåßò!" allcapstext = "Ãéá ðáñÜäåéãìá:
     [:line]" violent1 = "Ï/ç [:nick] åßíáé Ýíá ðïëý åðéèåôéêü Üôïìï. ÅðéôÝèçêå óå Üëëïõò [:attacks] öïñÝò." violent2 = "Ï/ç [:nick] äåí ìðüñåóå åðßóçò íá óõãêñáôÞóåé ôá íåýñá ôïõ/ôçò. ÅðéôÝèçêå [:attacks] öïñÝò óå Üëëïõò ÷ñÞóôåò." violent3 = "Êáíåßò äåí åðéôÝèçêå óå êáíÝíáí. ¼ëïé Þôáí öéëéêïß." violenttext = "Ãéá ðáñÜäåéãìá:
     [:line]" attacked1 = "Êáíåßò äåí öáßíåôáé íá óõìðáèåß ôïí/ôçí [:nick]. Ôïõ åðéôÝèçêáí [:attacks] öïñÝò." attacked2 = "Ï/ç [:nick] ìïéÜæåé íá åßíáé åðßóçò áíåðéèýìçôïò. Ôïõ åðéôÝèçêáí [:attacks] öïñÝò." attackedtext = "Ãéá ðáñÜäåéãìá:
     [:line]" gotkick1 = "Ï/ç [:nick] äåí åßíáé êáé ðïëý äçìïöéëÝò Üôïìï. Ôïõ/ôçò Ýêáíáí kick [:kicks] öïñÝò!" gotkick2 = "Ï/ç [:nick] ìïéÜæåé íá åßíáé Ýíá åðßóçò ìéóçôü Üôïìï. ÄÝ÷ôçêå [:kicks] kicks." kicktext = "Ãéá ðáñÜäåéãìá:
     [:line]" joins = "Ï/ç [:nick] äåí ìðïñïýóå íá áðïöáóßóåé áí èá ìåßíåé Þ èá öýãåé áðü ôï êáíÜëé, ìðáßíïíôáò [:joins] öïñÝò óå áõôü." kick1 = "[:nick]: äéêáéïóýíç Þ ðáñÜíïéá; ÐÜíôùò Ýêáíå kick óå [:kicked] Üôïìá." kick2 = "Óôç äåýôåñç èÝóç, ï/ç [:nick] Ýêáíå kick óå [:kicked] Üôïìá." kick3 = "Åäþ ôá ðñÜãìáôá åßíáé ìÜëëïí ÷áëáñÜ! ÊáíÝíáò äåí Ýêáíå kicks :)" words1 = "Ï/ç [:nick] êáôÜöåñå íá ãñÜøåé [:words] ëÝîåéò." words2 = "Óå áíôßèåóç ìå ôïí/ôçí [:oldnick], ï/ç [:nick] áêïëïýèçóå ìå [:words] ëÝîåéò." words3 = "Êáíåßò äåí åßðå ôßðïôá... ôé ðåñßåñãï êáíÜëé..." mono1 = "Ï/ç [:nick] ìïíïëïãåß ðïëý, ãñÜöïíôáò ðÜíù áðü 5 ãñáììÝò óôç óåéñÜ [:monos] öïñÝò!" mono2 = "Aëëïò Ýíáò ìïíá÷éêüò ÷ñÞóôçò Þôáí ï/ç [:nick] ðïõ êáôÜöåñå íá ìïíïëïãÞóåé [:monos] öïñÝò." wpl1 = "Ï/ç [:nick] Ýãñáøå êáôÜ ìÝóï üñï [:wpl] ëÝîåéò áíÜ ãñáììÞ." wpl2 = "Ï ìÝóïò üñïò ôïõ êáíáëéïý Þôáí [:avg] ëÝîåéò áíÜ ãñáììÞ." long1 = "Ï/ç [:nick] Ýãñáøå ôéò ìåãáëýôåñåò ãñáììÝò, ìå ìÝóï üñï [:letters] ÷áñáêôÞñùí áíÜ ãñáììÞ." long2 = "Ï ìÝóïò üñïò óôï [:channel] Þôáí [:avg] ÷áñáêôÞñåò áíÜ ãñáììÞ." short1 = "Ï/ç [:nick] Ýãñáøå ôéò ìéêñüôåñåò ãñáììÝò, ìå ìÝóï üñï [:letters] ÷áñáêôÞñùí áíÜ ãñáììÞ." short2 = "Ï/ç [:nick] Þôáí åðßóçò ðïëý ëáêùíéêüò, ìå ìÝóï üñï [:letters] ÷áñáêôÞñùí." foul1 = "Ï/ç [:nick] áðïäåß÷èçêå üôé îåðåñíÜåé ôá üñéá, ÷ñçóéìïðïéþíôáò êáôÜ [:per]% Üóåìíï ëåîéëüãéï" foul2 = "Åðßóçò ï/ç [:nick] áêïëïýèçóå ìå ðïóïóôü [:per]%." foul3 = "Êáíåßò äåí ìßëçóå Üó÷çìá óôï [:channel]!" foultext = "Ãéá ðáñÜäåéãìá:
     [:line]" smiles1 = "Ï/ç [:nick] öÝñíåé åõôõ÷ßá óôïí êüóìï, ÷ñçóéìïðïéþíôáò ÷áìüãåëá óå ðïóïóôü [:per]% :)" smiles2 = "Åðßóçò ï/ç [:nick] ÷áìïãÝëáóå óå ðïóïóôü [:per]%." smiles3 = "Êáíåßò äåí ÷áìïãåëÜåé óôï [:channel]! ÌÞðùò åßíáé þñá íá áíåâïýìå ëßãï;" sad1 = "Ï/ç [:nick] öáßíåôáé íá ìçí Ý÷åé êÝöéá áõôÞ ôçí ðåñßïäï. ×ñçóéìïðïßçóå èëéììÝíá ðñïóùðÜêéá óå ðïóïóôü [:per]% :(" sad2 = "Ï/ç [:nick] åßíáé åðßóçò Ýíá èëéììÝíï Üôïìï, ðïõ êáôóïýöéáóå óå ðïóïóôü [:per]%." sad3 = "Êáíåßò äåí åßíáé êáôóïýöçò óôï [:channel]! Ôé ÷áñïýìåíï êáíÜëé :-)" month = "Éáíïõáñßïõ Öåâñïõáñßïõ Ìáñôßïõ Áðñéëßïõ Ìáúïõ Éïõíßïõ Éïõëßïõ Áõãïýóôïõ Óåðôåìâñßïõ Ïêôùâñßïõ Íïåìâñßïõ Äåêåìâñßïõ" day = "ÊõñéáêÞ ÄåõôÝñá Ôñßôç ÔåôÜñôç ÐÝìðôç ÐáñáóêåõÞ ÓÜââáôï" ## Topics bignumtopic = "ÌåãÜëïé áñéèìïß" othernumtopic = "Aëëïé åíäéáöÝñïíôåò áñéèìïß" latesttopic = "Ôåëåõôáßá topics" activetimestopic = "Ïé ðéï åíåñãÝò þñåò" activenickstopic = "Ïé ðéï åíåñãïß ÷ñÞóôåò" activenickbyhourtopic = "Ïé ðéï åíåñãïß ÷ñÞóôåò áíÜ þñá" mostwordstopic = "Ïé ðéï äçìïöéëåßò ëÝîåéò" referencetopic = "Ôï ðéï äçìïöéëÝò øåõäþíõìï" smileytopic = "Smileys :-)" karmatopic = "Ôïõ êÜñìá ôïõ [:channel]" urlstopic = "Ïé ðéï äçìïöéëåßò äéåõèýíóåéò" chartstopic = "ÌïõóéêÝò åðéôõ÷ßåò óôï [:channel]" notopic = "Äåí äçëþèçêå êÜðïéï topic óôï êáíÜëé." mostnickstopic = "×ñÞóôåò ìå ôá ðåñéóóüôåñá øåõäþíõìá" bylinetopic = "[:date] áðü [:nick] óôéò [:time]" dailyactivitytopic = "ÇìåñÞóéá äñáóôçñéüôçôá (ôéò ôåëåõôáßåò [:n] çìÝñåò)" activegenderstopic = "Ôï ðéï åíåñãü öýëï" ## Other text totallines = "Óõíïëéêüò áñéèìüò ãñáììþí [:lines]." totalnicks = "Åðßóçò, õðÞñîáí êáé Üëëïé [:totalnicks] ÷ñÞóôåò." totaltopic = "Ôï topic äçëþèçêå [:total] öïñÝò." nick = "Øåõäþíõìï" names = "Ïíüìáôá ðïõ ÷ñçóéìïðïéÞèçêáí" url = "Äéåýèõíóç" numberlines = "Áñéèìüò ãñáììþí" randquote = "Ôõ÷áßá öñÜóç" userpic = "Öùôïãñáößá" nottop = "Äåí êáôÜöåñáí íá öôÜóïõí üëïé óôçí êïñõöÞ:" word = "ËÝîç" numberuses = "Óõ÷íüôçôá" show_words = "Áñéèìüò ëÝîåùí" show_time = "Ðüôå;" show_wpl = "ËÝîåéò áíÜ ãñáììÞ" show_cpl = "×áñáêôÞñåò áíÜ ãñáììÞ" show_lastseen = "Ôåëåõôáßá åßóïäïò" lastused = "Ôåëåõôáßá ÷ñçóéìïðïéÞèçêå áðü" smiley = "Smiley" karma = "ÊÜñìá" goodkarma = "Êáëü êÜñìá áðü" badkarma = "Êáêü êÜñìá áðü" lastseen1 = "[:days] çìÝñá ðñéí" lastseen2 = "[:days] çìÝñåò ðñéí" today = "ÓÞìåñá" pagetitle1 = "ÓôáôéóôéêÜ ãéá ôï [:channel] óôï [:network] áðü [:maintainer]." pagetitle2 = "Óôïé÷åßá ãéá " pagetitle3 = "Ãéá ôçí ÷ñïíéêÞ ðåñßïäï ôùí [:days] çìåñþí, [:nicks] ÷ñÞóôåò óõíïìßëçóáí óôï [:channel]." stats_gen_by = "Ôá óôáôéóôéêÜ äçìéïõñãÞèçêáí ìå ôï [:pisg_url] v[:version]" author = "pisg áðü ôïí [:author_url] êáé Üëëïõò" stats_gen_in = "Ôá óôáôéóôéêÜ äçìéïõñãÞèçêáí óå [:time]" hours = "þñåò" minutes = "ëåðôÜ" seconds = "äåõôåñüëåðôá" and = "êáé" names1 = "ïíüìáôá" names2 = "üíïìá" gender = "Öýëï" gender_f = "Èçëõêü" gender_m = "Áñóåíéêü" gender_b = "Bot" song = "Ôñáãïýäé" numberplayed = "Ðüóï óõ÷íÜ ðáß÷ôçêå" playedby = "Ôåëåõôáßá ðáß÷ôçêå áðü" # Mouse-over titles pisghomepage = "Ðçãáßíåôå óôç óåëßäá ôïõ pisg" authorhomepage = "Ðçãáßíåôå óôç óåëßäá ôïõ äçìéïõñãïý" newwindow = "Áíïéãìá óå íÝï ðáñÜèõñï:" mailto = "ÁðïóôïëÞ mail óå"
### Hebrew mostop1 = "[:nick] [:ðúï:ðúðä:] [:ops] àåôéí áòøåõ..." mostop2 = "[:nick] [:äéä:äééúä:] âí ãé [:îðåîñ:îðåîñú:]: [:ops] àåôéí î [:îîðå:îîðä:]." mostop3 = "îåæø, ìà ðúðå àó àåô á [:channel]!" mostdeop1 = "[:nick] [:äåà:äéà:] äùøéó ùì äòøåõ: [:deops] äåøãåú àåôéí!" mostdeop2 = "[:nick] [:äåøéã:äåøéãä:] [:deops] àåôéí." mostdeop3 = "ååàå! àó àçã ìà äåøéã àåôéí á [:channel]!" mostvoice1 = "[:nick] [:ðúï:ðúðä:] [:voices] ååééñéí áòøåõ..." mostvoice2 = "[:nick] [:äéä:äééúä:] âí ãé [:îðåîñ:îðåîñú:]: [:voices] ååéñéí î[:îîðå:îîðä:]." mostvoice3 = "îåæø, ìà ðúðå ùåí ååéñ á [:channel]!" mostdevoice1 = "[:nick] [:àåäá:àåäáú:] ìäåøéã ååéñéí îàðùéí! ñê äëì [:devoices] äåøãåú." mostdevoice2 = "[:nick] [:äéä:äééúä:] ÷øåá/ä: ñê äëì [:devoices] äåøãåú." mostdevoice3 = "ìà äåøéãå àó ååéñ á [:channel]!" mosthalfop1 = "[:nick] [:ðúï:ðúðä:] [:halfops] çöàé-àåô áòøåõ..." mosthalfop2 = "[:nick] [:äéä:äééúä:] âí ãé [:îðåîñ:îðåîñú:]: [:halfops] ðúðå òì [:éãå:éãä:]." mosthalfop3 = "îåæø, ìà ðúðå çöàé-àåô á [:channel]!" mostdehalfop1 = "[:nick] [:äåà:äéà:] äùøéó ùì äòøåõ, òí [:dehalfops] äåøãåú çöàé-àåôéí" mostdehalfop2 = "[:nick] [:äåøéã:äåøéãä:] [:dehalfops] çöàé-àåôéí." mostdehalfop3 = "îåæø, ìà äåøéãå çöàé-àåô á [:channel]!" action1 = "[:nick] úîéã [:ãåàâ:ãåàâú:] ìäâéã ìðå îä [:äåà:äéà:] òåùä: [:actions] à÷ùðéí!" action2 = "ëîå ëï, âí [:nick] [:àåîø:àåîøú:] ìðå îä ðùîò òí [:actions] 'à÷ùðéí'" action3 = "àéï 'à÷ùðéí' áòøåõ [:channel]!" actiontext = "ìãåâîà, ëîå æä:
     [:line]" question1 = "äàí [:nick] [:èéôù:èéôùä:] àå ñúí [:ùåàì:ùåàìú:] îìéåï ùàìåú? [:per]% ùåøåú äëéìå ùàìä!" question2 = "âí [:nick] ìà [:éãò:éãòä:] äøáä. [:per]% îäùåøåú [:ùìå:ùìä:] äéå ùàìåú." question3 = "àó àçã ìà ùàì ëàï ùàìåú; òøåõ ùì âàåðéí?" shout1 = "äëé [:øåòù:øåòùú:] [:äéä:äééúä:] [:nick], [:ùöò÷:ùöò÷ä:] [:per]% îäæîï!" shout2 = "îúçøä òì äëáåã ìúåàø [:äéä:äééúä:] [:nick], [:ùöò÷:ùöò÷ä:] [:per]% îäæîï!" shout3 = "ëåìðå øâåòéí áòøåõ äæä? àó àçã ìà öò÷!" allcaps1 = "ðøàä ùäùéôè ùì [:nick] ÷öú ú÷åò: [:per]% îäæîï [:äåà:äéà:] ëúá/ä áàåúéåú âãåìåú." allcaps2 = "[:nick] ôùåè [:ùëç:ùëçä:] ìëáåú àú ä CapsLock [:ùìå:ùìä:]. [:äåà:äéà:] [:ëúá:ëúáä:] áàåúéåú âãåìåú [:per]% îäæîï." allcaps3 = "ëåìí ùîøå òì äùéôè ùìäí úçú ùìéèä :)" allcapstext = "ìãåâîà, ëîå æä:
     [:line]" violent1 = "[:nick] [:äåà:äéà:] áðàãí îàåã àâøéñéáé. [:ú÷ó:ú÷ôä:] àçøéí [:attacks] ôòîéí." violent2 = "[:nick] ìà [:éëåì:éëåìä:] ìùìåè áàâøñéáéåú [:ùìå:ùìä:]. [:äåà:äéà:] [:äöé÷:äöé÷ä:] ìàçøéí [:attacks] ôòîéí." violent3 = "àó àçã ëàï ìà äéëä àó àçã... î÷åí çáøåúé!" violenttext = "ìãåâîà, ëê:
     [:line]" attacked1 = "[:îñëï:îñëðä:] [:nick], àó àçã ìà àåäá [:àåúå:àåúä:]. [:äåà:äéà:] [:äåú÷ó:äåú÷ôä:] [:attacks] ôòîéí." attacked2 = "[:nick] âí ìà äëé [:àäåã:àäåãä:]. [:äåà:äéà:] [:äåëä:äåëúä:] [:attacks] ôòîéí." attackedtext = "ìãåâîà, ëê:
     [:line]" gotkick1 = "[:nick] ìà [:äéä:äééúä:] äëé [:ôåôåìøé:ôåôåìøéú:], å[:ðáòè:ðáòèä:] [:kicks] ôòîéí!" gotkick2 = "[:nick] [:äéä:äééúä:] [:ùðåà:ùðåàä:] âí: [:÷éáì:÷éáìä:] [:kicks] áòéèåú." kicktext = "ìãåâîà, ëê:
     [:line]" joins = "[:nick] ìà [:éëì:éëìä:] ìäçìéè äàí ìäéùàø àå ììëú. [:joins] ëðéñåú ðñôøå áñê äëì!" kick1 = "[:nick] [:äåà:äéà:] àåô [:äåâï:äåâðú:], àå ñúí [:îèåøó:îèåøôú:], ù[:áòè:áòèä:] áñê äëì [:kicked] àðùéí!" kick2 = "äîúçøä ùì [:oldnick] [:äåà:äéà:] [:nick], [:áòè:áòèä:] [:kicked] àðùéí." kick3 = "àåôéí ðçîãéí éù ìðå ôä (ëðøàä éùðéí), ëé äí ìà áòèå áàó àçã!" words1 = "[:nick] [:àîø:àîøä:] [:words] îéìéí!" words2 = "äîúçøä ùì [:oldnick], äìà [:äåà:äéà:] [:nick], ìà [:ãéáø:ãéáøä:] ëì ëê äøáä: ø÷ [:words] îéìéí." words3 = "áåàðä àéæä òøåõ ù÷è, àó àçã ìà àîø àó îéìä..." mono1 = "[:nick] [:îãáø:îãáøú:] äøáä [:ìòöîå:ìòöîä:] [:äåà:äéà:] [:ëúá:ëúáä:] éåúø î 5 ùåøåú áøöó [:monos] ôòîéí!" mono2 = "òåã [:îúáåãã:îúáåããú:] [:äåà:äéà:] [:nick], ù[:äöìéç:äöìéçä:] ìäâéò ì [:monos] ôòîéí." wpl1 = "[:nick] [:ëúá:ëúáä:] áîîåöò [:wpl] îéìéí ìùåøä." wpl2 = "äîîåöò ùì äòøåõ äåà [:avg] îéìéí ìùåøä." long1 = "[:nick] [:ëúá:ëúáä:] àú äùåøåú äàøåëåú áéåúø! áîîåöò [:letters] àåúéåú ìùåøä." long2 = "äîîåöò ùì [:channel] äéä [:avg] àåúéåú ìùåøä." short1 = "[:nick] [:ëúá:ëúáä:] àú äùåøåú ä÷öøåú áéåúø! áîîåöò: [:letters] àåúéåú ìùåøä." short2 = "ì [:nick] âí äéå áòéåú áìùåï, åäîîåöò [:ùìå:ùìä:] äåà [:letters] àåúéåú." foul1 = "ì [:nick] éù ôä ãé îìåëìê. [:per]% [:îîéìåúéå:îîéìåúéä:] äéå ðéáåì ôä." foul2 = "[:nick] âí [:äúçøä:äúçøúä:] òì äúåàø, òí [:per]% ùì ðéáåìé ôä." foul3 = "àó àçã á [:channel] ìà î÷ìì! àúí éåöàéí áëìì äçåöä àé ôòí?" foultext = "ìãåâîà, ëê:
     [:line]" smiles1 = "[:nick] [:îáéà:îáéàä:] ùîçä ìòåìí. [:per]% îäùåøåú [:ùìå:ùìä:] äëéìå ñîééìéí :)" smiles2 = "[:nick] âí ìà äáðàãí äëé òöåá áòåìí, òí [:per]% îäæîï." smiles3 = "àó àçã ìà îçééê á [:channel]! çáø'ä, úúòåããå ÷öú!" sad1 = "[:nick] [:ðøàä:ðøàéú:] [:òöåá:òöåáä:] ìîãé: [:per]% îäùåøåú äëéìå ôøöåó òöåá :(" sad2 = "[:nick] [:äåà:äéà:] âí àãí òöåá [:per]% îäæîï." sad3 = "àó àçã ìà òöåá á [:channel]! àéæä òøåõ ùîç! :-)" month = "éðåàø ôáøåàø îøõ àôøéì îàé éåðé éåìé àåâåñè ñôèîáø àå÷èåáø ðåáîáø ãöîáø" day = "øàùåï ùðé ùìéùé øáéòé çîéùé ùéùé ùáú" ## Topics bignumtopic = "äîñôøéí äâãåìéí" othernumtopic = "îñôøéí îòðééðéí àçøéí" latesttopic = "èåôé÷éí àçøåðéí" activetimestopic = "äùòåú äëé ôòéìåú" activenickstopic = "äëéðåééí äëé ôòéìéí" activenickbyhourtopic = "äëéðåééí äëé ôòéìéí òì ôé ùòåú" mostwordstopic = "äîéìéí ùäåæëøå äëé äøáä" referencetopic = "äëéðåé ùäúééçñå àìéå äëé äøáä" urlstopic = "äëúåáåú ùäåæëøå äëé äøáä ôòîéí" notopic = "îòåìí ìà ùîå èåôé÷ áòøåõ æä." mostnickstopic = "äîùúîùéí òí äëé äøáä ëéðåééí" bylinetopic = "[:date] òì éãé [:nick] á [:time]" dailyactivitytopic = "(ôòéìåú éåîéú ([:n] éîéí àçøåðéí" smileytopic = "ôøöåôéí îåáéìéí :-)" chartstopic = "[:òøåõ] îöòã äîåæé÷ä" karmatopic = "÷àøîä [:channel]" activegenderstopic = "äîéï ùîãáø äëé äøáä" ## Other text totallines = "ñê äëì îñôø äùåøåú: [:lines]." totalnicks = "àâá, äéå [:totalnicks] ðé÷éí àçøéí." totaltopic = "ùéðå èåôé÷ [:total] ôòîéí." nick = "ëéðåé" names = "ùîåú ùäùúîùå áäí" url = "ëúåáú" numberlines = "îñôø äùåøåú" randquote = "öéèåè à÷øàé" userpic = "úîåðú îùúîù" nottop = "àìä ìà äöìéçå ìäâéò ìôéñâä:" word = "îéìä" numberuses = "îñôø äîùúîùéí" show_words = "îñôø äîéìéí" show_time = "îúé?" show_wpl = "îéìéí ìùåøä" show_cpl = "àåúéåú ìùåøä" show_lastseen = "ðøàä ìàçøåðä" lastused = "äàçøåï ùäùúîù" lastseen1 = "[:days] àúîåì" lastseen2 = "[:days] éîéí ìôðé äéåí" today = "äéåí" pagetitle1 = "ñèèéñèé÷ä ùì äòøåõ [:channel] áøùú [:network] òì éãé [:maintainer]" pagetitle2 = "ñèèéñèé÷åú ðåöøå áéåí" pagetitle3 = "áîäìê ú÷åôä æå ùì [:days] éîéí, ñê ùì [:nicks] ëéðåééí ùåðéí ðøàå áòøåõ [:channel]." stats_gen_by = "Stats generated by [:pisg_url] v[:version]" author = "pisg by [:author_url] and others" stats_gen_in = "æîï éöéøú äñèèéñèé÷ä: [:time]" hours = "ùòåú" minutes = "ã÷åú" seconds = "ùðéåú" and = "å" names1 = "ùîåú" names2 = "ùí" karma = "÷àøîä" badkarma = "÷àøîä øòä òì éãé" goodkarma = "÷àøîä èåáä òì éãé" gender_m = "æëø" gender = "îéï" gender_b = "áåè" gender_f = "ð÷áä" smiley = "ôøöåó" numberplayed = "áàéæå úãéøåú îðåâï" song = "ùéø" playedby = "ìàçøåðä ðåâï òì éãé" # Mouse-over titles pisghomepage = "àúø äáéú ùì pisg" authorhomepage = "àúø äáéú ùì äéåöø" newwindow = "ôúç áçìåï çãù:" mailto = "ùìç ãåàø àì"
### Bulgarian mostop1 = "[:nick] äàäå [:ops] op-à â êàíàëà..." mostop2 = "[:nick] ñúùî áåøå ìíîãî [:ëþáåçåí:ëþáåçíà:]: [:ops] op-à." mostop3 = "Ñòðàííî, íå áåøå äàäåí op â [:channel]!" mostdeop1 = "[:nick] å øåðèôà íà êàíàëà. Deop-íà [:deops] ïúòè." mostdeop2 = "[:nick] ìàõíà [:deops] op-à." mostdeop3 = "Èõà, íå áå îòíåò íèòî åäèí op â [:channel]!" mostvoice1 = "[:nick] äàäå [:voices] voice-à â êàíàëà..." mostvoice2 = "[:nick] ñúùî å ìíîãî [:ó÷òèâ:ó÷òèâà:]: äàäå [:voices] voice-à." mostvoice3 = "Ñòðàííî, íå ñà äàâàíè voice-îâå â [:channel]!" mostdevoice1 = "[:nick] îáè÷à äà âçèìà äóìàòà (voice-à) îò õîðàòà: [:devoices] ïúòè." mostdevoice2 = "[:nick] áåøå áëèçî äî ñúùîòî: [:devoices] devoice-à." mostdevoice3 = "Íå áÿõà îòíåòè voice-îâå â [:channel]!" mosthalfop1 = "[:nick] äàðè [:halfops] halfop-à â êàíàëà..." mosthalfop2 = "[:nick] å [:äàë:äàëà:] ñàìî [:halfops] halfop-a." mosthalfop3 = "Ñòðàííî, íå å äàâàí halfop â [:channel]!" mostdehalfop1 = "[:nick] å øåðèôà íà êàíàëà. Ìàõíà [:dehalfops] halfops." mostdehalfop2 = "[:nick] dehalfop-íà [:dehalfops] ÷îâåêà." mostdehalfop3 = "Èõà, íå áå îòíåò íèòî åäèí halfop â [:channel]!" action1 = "[:nick]âèíàãè íè óâåäîìÿâà êàêâî ïðàâè: [:actions] äåéñòâèÿ!" action2 = "Îñâåí òîâà, [:nick] íè êàçâà êàêâî ñòàâà ñ [:actions] äåéñòâèÿ." action3 = "Íÿìà äåéñòâèÿ â [:channel]!" actiontext = "Íàïðèìåð òàêà:
     [:line]" question1 = "[:nick] [:ãëóïàâ:ãëóïàâà:] ëè å èëè ïðîñòî çàäàâà ìíîãî âúïðîñè? [:per]% oò ðåäîâåòå [:ìó:é:] ñúäúðæàõà âúïðîñèòåëíà!" question2 = "[:nick] ñúùî íå çíàåøå ìíîãî [:per]% îò ðåäîâåòå [:ìó:é:] áÿõà âúïðîñè." question3 = "Íèêîé íå çàäàäå âúïðîñ â òóêà. Âñè÷êè ñà ãåíèè ;)" shout1 = "Íàé-ãðúìîãëàñíèÿ áåøå [:nick], êîéòî êðåùåøå ïðåç [:per]% îò âðåìåòî!" shout2 = "Äðóãèÿ êàâãàäæèÿ áåøå [:nick], êîéòî âèêàøå ïðåç [:per]% îò âðåìåòî!" shout3 = "Íèêîé íå å ïîâèøàâàë òîí, óàó." allcaps1 = "Èçãëåæäà shift-à íà [:nick] çàÿæäà: [:per]% îò âðåìåòî ïèñà ñ ÃËÀÂÍÈ ÁÓÊÂÈ." allcaps2 = "[:nick] ïðîñòî çàáðàâè äà èçêëþ÷è Caps-Lock-à ñè. [:Òîé:Òÿ:] ïèñà ñ ÃËÀÂÍÈ ÁÓÊÂÈ [:per]% îò âðåìåòî." allcaps3 = "Âñè÷êè êîíòðîëèðàò shift-a ñè. :)" allcapstext = "Åòî íàïðèìåð:
     [:line]" violent1 = "[:nick] å ìíîãî àãðåñèâíà ëè÷íîñò. [:Òîé:Òÿ:] àòàêóâà äðóãèòå [:attacks] ïúòè." violent2 = "[:nick] ñúùî íå ìîæå äà êîíòðîëèðà àãðåñèÿòà ñè. Íàïåðäàøè äðóãèòå [:attacks] ïúòè." violent3 = "Íèêîé íå óäàðè íèêîãî. Âñè÷êè áÿõà ïðèÿòåëñêè íàñòðîåíè." violenttext = "Åòî íàïðèìåð:
     [:line]" attacked1 = "Ãîðêèÿ [:nick], íèêîé íå [:ãî:ÿ:] õàðåñâàøå. Íàáèõà [:ãî:ÿ:] [:attacks] ïúòè." attacked2 = "[:nick] èçãëåæäà ñúùî íå áåøå õàðåñâàí. Íàïåðäàøèõà [:ãî:ÿ:] [:attacks] ïúòè." attackedtext = "Åòî íàïðèìåð:
     [:line]" gotkick1 = "[:nick] õè÷ íå ãî îáè÷àõà. Ðèòíàõà [:ãî:ÿ:] [:kicks] ïúòè!" gotkick2 = "[:nick] ñúùî ãî ìðàçåõà: [:kicks] èçÿäå ðèòíèêà." kicktext = "Íàïðèìåð:
     [:line]" joins = "[:nick]Íå ìîæà äà ðåøè äàëè ùå îñòàíå èëè ùå íàïóñíå: [:joins] ïúòè å âëèçàë â êàíàëà!" kick1 = "[:nick] èëè å ïîëóäÿë(à), èëè ïðîñòî áåøå ñëàá îïåðàòîð. Ðèòíà îáùî [:kicked] ÷îâåêà!" kick2 = "[:nick] å [:âåðåí:âÿðíà:] ïîñëåäîâàòåë(êà) íà [:oldnick], ðàçäàäå îêîëî [:kicked] ðèòíèêà." kick3 = "Oïåðàòîðèòå òóêà ñà äîáðè, íèêîé íå áåøå ðèòíàò." words1 = "[:nick] êàçà îáùî [:words] äóìè!" words2 = "Ïîäãëàñíèêà íà [:oldnick] - [:nick], íå ãîâîðåøå òîëêîâà ìíîãî: [:words] äóìè." words3 = "Íèêîé íèùî íå êàçà... Êàêúâ ñòðàíåí êàíàë..." mono1 = "[:nick] ãîâîðè ìíîãî íà ñåáå ñè. [:Òîé:Òÿ:] íàïèñà 5 ïîðåäíè ðåäà [:monos] ïúòè!" mono2 = "Äðóãèÿ ñàìîòåí áåøå [:nick], êîéòî ïîñòèãíà òîâà [:monos] ïúòè." wpl1 = "[:nick] ïèñà ñðåäíî ïî [:wpl] äóìè íà ðåä." wpl2 = "Ñðåäíîòî çà [:channel] áåøå [:avg] äóìè íà ðåä." long1 = "[:nick] Ïèñà íàé-äúëãèòå ðåäîâå - ñðåäíî ñ ïî [:letters] ñèìâîëà." long2 = "Ñðåäíîòî çà [:channel]: [:avg] ñèìâîëà íà ðåä." short1 = "[:nick] ïèñà íàé-êúñèòå ðåäîâå - ñðåäíî ñ ïî [:letters] ñèìâîëà." short2 = "[:nick] ñúùî ñè ïåñòåøå äóìèòå - ñðåäíî ñ ïî [:letters] ñèìâîëà íà ðåä." foul1 = "[:nick] èìà ìðúñíî (ïîä)ñúçíàíèå. [:per]% îò äóìèòå, êîèòî êàçà, áÿõà ìðúñíè." foul2 = "[:nick] íàêàðà è êàðóöàðèòå äà ñå èç÷åðâÿò - ïðåç [:per]% îò âðåìåòî." foul3 = " [:channel] âñè÷êè ñà êóëòóðíè." foultext = "Åòî íàïðèìåð:
     [:line]" smiles1 = "[:nick] íîñè ùàñòèå íà ñâåòà. [:per]% îò ðåäîâåòå [:ìó:é:] ñúäúðæàõà óñìèâêè :)" smiles2 = "[:nick] ñúùî íå å [:òúæåí:òúæíà:], óñìèõâàøå ñå [:per]% îò âðåìåòî." smiles3 = "Íèêîé íå ñå óñìèõâà â [:channel]! Ðàçâåñåëåòå ñå ìîì÷åòà è ìîìè÷åòà!" sad1 = "[:nick] èçãëåæäà [:òúæåí:òúæíà:] â ìîìåíòà: [:per]% îò ðåäîâåòå ìó ñúäúðæàõà ãðèìàñè :(" sad2 = "[:nick] ñúùî å [:òúæåí:òúæíà:], ïëà÷åøå [:per]% îò âðåìåòî." sad3 = "Íèêîé íå å òúæåí â [:channel]! Êàêúâ ùàñòëèâ êàíàë! :)" month = "ßíóàðè Ôåâðóàðè Ìàðò Àïðèë Ìàé Þíè Þëè Àâãóñò Ñåïòåìâðè Îêòîìâðè Íîåìâðè Äåêåìâðè" day = "Íåäåëÿ Ïîíåäåëíèê Âòîðíèê Ñðÿäà ×åòâúðòúê Ïåòúê Ñúáîòà" ## Topics - Çàãëàâèÿ bignumtopic = "Ãîëåìè ÷èñëà" othernumtopic = "Äðóãè èíòåðåñíè ÷èñëà" latesttopic = "Ïîñëåäíè òåìè" activetimestopic = "Êîãà âñúùíîñò ïðèêàçâàìå òóê?" activenickstopic = "Íàé-àêòèâíè" activenickbyhourtopic = "Íàé-àêòèâíè ïî ÷àñîâå" mostwordstopic = "Íàé-èçïîëâàíè äóìè" referencetopic = "Íàé-ñïîìåíàâàíè ïñåâäîíèìè" karmatopic = "[:channel] êàðìà" urlstopic = "Íàé-ñïîìåìåíàâàíè web-àäðåñè" notopic = "Íèêîãà íå å èìàëî òåìà â êàíàëà" mostnickstopic = "Õîðà ñ íàé-ìíîãî ïñåâäîíèìè" bylinetopic = "îò [:nick] íà [:date] â [:time]" dailyactivitytopic = "Àêòèâíîñò ïî äíè (ïîñëåäíèòå [:n])" activegenderstopic = "Ïî-àêòèâåí ïîë" acrivegenderstopic = "Íàé-àêòèâåí ïîë" smileytopic = "Ñìàéëèòà :-)" chartstopic = "[:channel] Òîï ëèñòè" ## Other text smiley = "Ñìàéëè" numberplayed = "Êîëêî ÷åñòî å èçïúëíÿâàíà" song = "Ïåñåí" playedby = "Ïîëñëåäíî èçïúëíåíà îò" totallines = "Îáù áðîé íà ðåäîâåòå: [:lines]." totalnicks = "Ìåæäó äðóãîòî, èìàëî å [:totalnicks] äðóãè ïñåâäîíèìè." totaltopic = "Òåìàòà å ñìåíÿíà [:total] ïúòè." nick = "Ïñåâäîíèì" names = "Èçïîëçâàíè èìåíà" url = "URL" numberlines = "Áðîé ðåäîâå" randquote = "Ïðîèçâîëíà ðåïëèêà" userpic = "Ñíèìêà" nottop = "Òåçè íå óñïÿõà äà ñòèãíàò ïî-íàãîðå" word = "Äóìà" numberuses = "Áðîé èçïîëçâàíèÿ" show_words = "Áðîé äóìè" show_time = "Êîãà?" show_wpl = "Äóìè íà ðåä" show_cpl = "Ñèìâîëè íà ðåä" show_lastseen = "Ïîñëåäíî âèäÿí" karma = "Êàðìà" goodkarma = "Äîáðà êàðìà îò" badkarma = "Ëîøà êàðìà îò" lastused = "Ïîñëåäíî èçïîëçâàí îò" lastseen1 = "â÷åðà" lastseen2 = "[:days] äåíà" today = "Äíåñ" pagetitle1 = "[:channel] @ [:network] ñòàòèñòèêà îò [:maintainer]" pagetitle2 = "Ñòàòèñòèêàòà å ãåíåðèðàíà â" pagetitle3 = "Ïî âðåìå íà [:days]-äíåâíèÿ ïåðèîä, [:nicks] ÷îâåêà ñà âçåëè ó÷àñòèå â [:channel]." stats_gen_by = "Ñòàòèñòèêàòà å ãåíåðèðàíà îò [:pisg_url] v[:version]" author = "pisg îò [:author_url] è äðóãè" stats_gen_in = "Ãåíåðèðàíà çà [:time]" hours = "÷àñà" minutes = "ìèíóòè" seconds = "ñåêóíäè" and = "è" names1 = "èìåíà" names2 = "èìå" gender = "Ïîë" gender_f = "Æåíà" gender_m = "Ìúæ" gender_b = "Áîò" # Mouse-over titles pisghomepage = "Îòèäåòå íà ñàéòà íà pisg" authorhomepage = "Îòèäåòå íà ñàéòà íà àâòîðèòå" newwindow = "Îòâîðè â íîâ ïðîçîðåö" mailto = "Ïîùà äî"
### Serbian (Cyrillic) mostop1 = "[:nick] је оповао [:ops] оÑоба на каналу..." mostop2 = "[:nick] је такође био баш дарежљив и оповао је [:ops] оÑоба на каналу" mostop3 = "Чудно, није било оповања на каналу [:channel]!" mostdeop1 = "[:nick] је шериф канала Ñа [:deops] деоповања." mostdeop2 = "[:nick] је деоповао [:deops] кориÑника." mostdeop3 = "Вао, није било деоповања на [:channel]!" mostvoice1 = "[:nick] је поделио [:voices] плуÑића на каналу..." mostvoice2 = "[:nick] је такође био веома дарежљив и поделио је [:voices] плуÑића." mostvoice3 = "Чудно, ниÑу дељени плуÑићи на каналу [:channel]!" mostdevoice1 = "[:nick] воли да одузима плуÑиће. Одузео је [:devoices] плуÑића." mostdevoice2 = "[:nick] је био близу Ñа одузетих [:devoices] плуÑића." mostdevoice3 = "Ðије било одузимања плуÑића на каналу [:channel]!" mosthalfop1 = "[:nick] је поделио [:halfops] ÑтатуÑа помоћног опа на каналу..." mosthalfop2 = "[:nick] је такође био веома дарежљив и поделио је [:halfops] помоћних опова ." mosthalfop3 = "Чудно, није било помоћних опова на каналу [:channel]!" mostdehalfop1 = "[:nick] је шериф канала одузимајући [:dehalfops] помоћних опова." mostdehalfop2 = "[:nick] је Ñкинуо [:dehalfops] помоћна опа." mostdehalfop3 = "Чудно, није било Ñкидања помоћних опова на каналу [:channel]!" action1 = "[:nick] нам увек Ñтавља до знања шта ради. [:actions] Ðкција!" action2 = "Такође и [:nick] нам је Ñаопштавао шта ради Ñа [:actions] акција." action3 = "Ðије било акција на [:channel]!" actiontext = "Ðа пример:
     [:line]" question1 = " Да ли [:nick] нема појма или превише поÑтавља питања? [:per]% његових редова завршава Ñа упитником!" question2 = "[:nick] такође много тога није знао. [:per]% редова Ñа упитником на крају." question3 = "Ðико ништа није питао. ЈеÑмо ли то Ñви генијалци?" shout1 = "ÐајглаÑнији је био [:nick], који је викао [:per]% времена проведеног на каналу!" shout2 = "Други галамџија је био [:nick], који је викао [:per]% времена проведеног на каналу!" shout3 = "Ðико није био глаÑан." allcaps1 = "Изгледа да Ñе [:nick]-у заглавио шифт: [:per]% времена је пиÑао ВЕЛИКИМ СЛОВИМÐ." allcaps2 = "[:nick] је заборавио да угаÑи [:his:her:] Caps-Lock. Куцао је ВЕЛИКИМ СЛОВИМР[:per]% времена проведеног на каналу." allcaps3 = "Сви Ñу имали Ñвоју шифт типку под контролом :)" allcapstext = "Ðа пример:
     [:line]" violent1 = " [:nick] је био веома агреÑиван. Ðападао је друге [:attacks] пута." violent2 = "[:nick] није могао да контролише [:his:her:] Ñвој беÑ. Изабрао је друге [:attacks] да напада за Ñвоје време проведено на каналу." violent3 = "Ðико није нападао оÑтале. Сви Ñу били пријатељÑки раÑположени." violenttext = "Као на овом примеру:
     [:line]" attacked1 = "Ðико није волео кориÑника [:nick]. Ðападнут је [:attacks] пута." attacked2 = "Изгледа да ни кориÑника [:nick] ниÑу волели. Ударен је [:attacks] пута." attackedtext = "Као на пример:
     [:line]" gotkick1 = "[:nick] није био баш популаран, избачен је Ñа канала [:kicks] пута!" gotkick2 = "Мрзели Ñу и кориÑника [:nick]. Избачен је [:kicks] пута." kicktext = "Као на пример:
     [:line]" joins = "[:nick] није могао да Ñе одлучи да ли да оÑтане или да оде. [:joins] пута је ушао на канал!" kick1 = "[:nick] је или луд или Ñамо фер. Избацио је Ñамо [:kicked] кориÑника!" kick2 = "Верни пратилац ÑтатуÑа оператора [:oldnick], [:nick], киковао је [:kicked] кориÑника." kick3 = "Овде Ñу опови дивни. Ðико није кикован!" words1 = "[:nick] је рекао укупно [:words] речи!" words2 = "Верни пратилац кориÑника [:oldnick], [:nick], такође не прича много: Ñамо [:words] речи." words3 = "Ðико ништа није рекао... ЗаиÑта чудан канал..." mono1 = "[:nick] је причао Ñам Ñа Ñобом. [:monos] пута је иÑпиÑао више од 5 редова узаÑтопно!" mono2 = "Такође уÑамљен био је и [:nick]. Водио је монолог [:monos] пута." wpl1 = "[:nick] је пиÑао проÑечно [:wpl] речи по реду." wpl2 = "ПроÑек на каналу је био [:avg] речи по реду." long1 = "[:nick] је пиÑао најдуже редове Ñа проÑечно [:letters] Ñлова." long2 = "Ðа [:channel] проÑечно је пиÑано [:avg] Ñлова по реду." short1 = "[:nick] је пиÑао најкраће редове Ñа проÑечно [:letters] Ñлова." short2 = "[:nick] је такође држао уÑта затворена. ПроÑечно [:letters] иÑпиÑаних Ñлова." foul1 = "[:nick] баш воли да пÑује. [:per]% онога што је пиÑао Ñу биле пÑовке! Срам те било!" foul2 = "[:nick] је такође пÑовао [:per]% времена проведеног на каналу." foul3 = "Ðико није пÑовао на [:channel]! :-)) Какви Ñу то људи?" foultext = "Као на пример:
     [:line]" smiles1 = "[:nick] доноÑти Ñвету Ñрећу :). У [:per]% његових редова има Ñмајли :)" smiles2 = "[:nick] је такође био веÑео. Смешио Ñе [:per]% времена проведеног на каналу." smiles3 = "Ðико Ñе не Ñмеши на каналу [:channel]! Разведрите Ñе БРЕ !." sad1 = "Изгледа да је [:nick] био много тужан. [:per]% редова завршавао је тужним лицем :(" sad2 = "[:nick] је такође био тужан. Плакао је [:per]% времена проведеног на каналу." sad3 = "Ðа [:channel] нико није тужан! Баш веÑео канал. :-)" month = "јануара фебруара марта априла маја јуна јула авгуÑта Ñептембра октобра новембра децембра" day = "недељу понедељак уторак Ñреду четвртак петак Ñуботу" ## Topics bignumtopic = "ОÑтале занимљиве активноÑти:" othernumtopic = "ОÑтале занимљивоÑти" latesttopic = "ПоÑледњих неколико топика" activetimestopic = "Интервали Ñа највише активниÑти" activenickstopic = "Ðајактивнији кориÑници" activenickbyhourtopic = "Ðајактивнији кориÑници по Ñату" mostwordstopic = "Ðајчешће употребљиване речи" referencetopic = "Ðајчешће поменут надимак" smileytopic = "Смајлији :o)" karmatopic = "[:channel] карма" urlstopic = "Ðајчешће поменута Интернет адреÑа" chartstopic = "[:channel] Музичке лиÑте" notopic = "Ðа овом каналу нико није поÑтавио топик" mostnickstopic = "КориÑници Ñа највише надимака" bylinetopic = "[:date] од [:nick] у [:time]" dailyactivitytopic = "ÐктивноÑти по дану (поÑледњих [:n] дана)" activegenderstopic = "Ðајчешћи пол" ## Other text totallines = "Укупан број редова: [:lines]." totalnicks = "УÑпут буди речено, било је још [:totalnicks] других надимака." totaltopic = "Топик је поÑтаван [:total] пута." nick = "Ðадимак" names = "Помињана имена" url = "URL" numberlines = "Број редова" randquote = "ÐаÑумични цитат" userpic = "Слика кориÑника" nottop = "ÐиÑу могли да уђу у групу од 35 најактивнијих:" word = "Реч" numberuses = "Број кориÑника" show_words = "Број речи" show_time = "Када?" show_wpl = "Речи по реду" show_cpl = "Слова по реду" show_lastseen = "ПоÑледњи пут виђен" lastused = "Задњи употребљен од" smiley = "Смајли" karma = "Карма" goodkarma = "Добра кармао д" badkarma = "Лоша карма од" lastseen1 = "јуче" lastseen2 = "пре [:days] дана" today = "данаÑ" pagetitle1 = "[:channel] @ [:network] ÑтатиÑтике направио [:maintainer]" pagetitle2 = "СтатиÑтика је обновљена у" pagetitle3 = "За време овог [:days]-дневног периода, појавило Ñе укупно [:nicks] различитих надимака на [:channel]." stats_gen_by = "СтатиÑтике генериÑао [:pisg_url] v[:version]" author = "pisg од аутора [:author_url] и оÑталих" stats_gen_in = "СтатиÑтике израђене за [:time]" hours = "чаÑова" minutes = "минута" seconds = "Ñекунди" and = "и" names1 = "имена" names2 = "име" gender = "Пол" gender_f = "ЖенÑко" gender_m = "Мушко" gender_b = "Бот" song = "ПеÑма" numberplayed = "Колико чеÑто пуштана" playedby = "ПоÑледњи је пуÑтио" # Mouse-over titles pisghomepage = "Иди на pisg Ñтраницу" authorhomepage = "Иди на ауторову Ñтраницу" newwindow = "Отвара у новом прозору:" mailto = "Е-пошта"
### Serbian (Latin) mostop1 = "[:nick] je opovao [:ops] osoba na kanalu..." mostop2 = "[:nick] je takođe bio baš darežljiv i opovao je [:ops] osoba na kanalu" mostop3 = "Čudno, nije bilo opovanja na kanalu [:channel]!" mostdeop1 = "[:nick] je šerif kanala sa [:deops] deopovanja." mostdeop2 = "[:nick] je deopovao [:deops] korisnika." mostdeop3 = "Vao, nije bilo deopovanja na [:channel]!" mostvoice1 = "[:nick] je podelio [:voices] plusića na kanalu..." mostvoice2 = "[:nick] je takođe bio veoma darežljiv i podelio je [:voices] plusića." mostvoice3 = "Čudno, nisu deljeni plusići na kanalu [:channel]!" mostdevoice1 = "[:nick] voli da oduzima plusiće. Oduzeo je [:devoices] plusića." mostdevoice2 = "[:nick] je bio blizu sa oduzetih [:devoices] plusića." mostdevoice3 = "Nije bilo oduzimanja plusića na kanalu [:channel]!" mosthalfop1 = "[:nick] je podelio [:halfops] statusa pomoćnog opa na kanalu..." mosthalfop2 = "[:nick] je takođe bio veoma darežljiv i podelio je [:halfops] pomoćnih opova ." mosthalfop3 = "Čudno, nije bilo pomoćnih opova na kanalu [:channel]!" mostdehalfop1 = "[:nick] je šerif kanala oduzimajući [:dehalfops] pomoćnih opova." mostdehalfop2 = "[:nick] je skinuo [:dehalfops] pomoćna opa." mostdehalfop3 = "Čudno, nije bilo skidanja pomoćnih opova na kanalu [:channel]!" action1 = "[:nick] nam uvek stavlja do znanja šta radi. [:actions] Akcija!" action2 = "Takođe i [:nick] nam je saopštavao šta radi sa [:actions] akcija." action3 = "Nije bilo akcija na [:channel]!" actiontext = "Na primer:
     [:line]" question1 = " Da li [:nick] nema pojma ili previÅ¡e postavlja pitanja? [:per]% njegovih redova zavrÅ¡ava sa upitnikom!" question2 = "[:nick] takoÄ‘e mnogo toga nije znao. [:per]% redova sa upitnikom na kraju." question3 = "Niko niÅ¡ta nije pitao. Jesmo li to svi genijalci?" shout1 = "Najglasniji je bio [:nick], koji je vikao [:per]% vremena provedenog na kanalu!" shout2 = "Drugi galamdžija je bio [:nick], koji je vikao [:per]% vremena provedenog na kanalu!" shout3 = "Niko nije bio glasan." allcaps1 = "Izgleda da se [:nick]-u zaglavio Å¡ift: [:per]% vremena je pisao VELIKIM SLOVIMA." allcaps2 = "[:nick] je zaboravio da ugasi [:his:her:] Caps-Lock. Kucao je VELIKIM SLOVIMA [:per]% vremena provedenog na kanalu." allcaps3 = "Svi su imali svoju Å¡ift tipku pod kontrolom :)" allcapstext = "Na primer:
     [:line]" violent1 = " [:nick] je bio veoma agresivan. Napadao je druge [:attacks] puta." violent2 = "[:nick] nije mogao da kontroliÅ¡e [:his:her:] svoj bes. Izabrao je druge [:attacks] da napada za svoje vreme provedeno na kanalu." violent3 = "Niko nije napadao ostale. Svi su bili prijateljski raspoloženi." violenttext = "Kao na ovom primeru:
     [:line]" attacked1 = "Niko nije voleo korisnika [:nick]. Napadnut je [:attacks] puta." attacked2 = "Izgleda da ni korisnika [:nick] nisu voleli. Udaren je [:attacks] puta." attackedtext = "Kao na primer:
     [:line]" gotkick1 = "[:nick] nije bio baÅ¡ popularan, izbaÄen je sa kanala [:kicks] puta!" gotkick2 = "Mrzeli su i korisnika [:nick]. IzbaÄen je [:kicks] puta." kicktext = "Kao na primer:
     [:line]" joins = "[:nick] nije mogao da se odluÄi da li da ostane ili da ode. [:joins] puta je uÅ¡ao na kanal!" kick1 = "[:nick] je ili lud ili samo fer. Izbacio je samo [:kicked] korisnika!" kick2 = "Verni pratilac statusa operatora [:oldnick], [:nick], kikovao je [:kicked] korisnika." kick3 = "Ovde su opovi divni. Niko nije kikovan!" words1 = "[:nick] je rekao ukupno [:words] reÄi!" words2 = "Verni pratilac korisnika [:oldnick], [:nick], takoÄ‘e ne priÄa mnogo: samo [:words] reÄi." words3 = "Niko niÅ¡ta nije rekao... Zaista Äudan kanal..." mono1 = "[:nick] je priÄao sam sa sobom. [:monos] puta je ispisao viÅ¡e od 5 redova uzastopno!" mono2 = "TakoÄ‘e usamljen bio je i [:nick]. Vodio je monolog [:monos] puta." wpl1 = "[:nick] je pisao proseÄno [:wpl] reÄi po redu." wpl2 = "Prosek na kanalu je bio [:avg] reÄi po redu." long1 = "[:nick] je pisao najduže redove sa proseÄno [:letters] slova." long2 = "Na [:channel] proseÄno je pisano [:avg] slova po redu." short1 = "[:nick] je pisao najkraće redove sa proseÄno [:letters] slova." short2 = "[:nick] je takoÄ‘e držao usta zatvorena. ProseÄno [:letters] ispisanih slova." foul1 = "[:nick] baÅ¡ voli da psuje. [:per]% onoga Å¡to je pisao su bile psovke! Sram te bilo!" foul2 = "[:nick] je takoÄ‘e psovao [:per]% vremena provedenog na kanalu." foul3 = "Niko nije psovao na [:channel]! :-)) Kakvi su to ljudi?" foultext = "Kao na primer:
     [:line]" smiles1 = "[:nick] donosti svetu sreću :). U [:per]% njegovih redova ima smajli :)" smiles2 = "[:nick] je takoÄ‘e bio veseo. SmeÅ¡io se [:per]% vremena provedenog na kanalu." smiles3 = "Niko se ne smeÅ¡i na kanalu [:channel]! Razvedrite se BRE !." sad1 = "Izgleda da je [:nick] bio mnogo tužan. [:per]% redova zavrÅ¡avao je tužnim licem :(" sad2 = "[:nick] je takoÄ‘e bio tužan. Plakao je [:per]% vremena provedenog na kanalu." sad3 = "Na [:channel] niko nije tužan! BaÅ¡ veseo kanal. :-)" month = "januara februara marta aprila maja juna jula avgusta septembra oktobra novembra decembra" day = "nedelju ponedeljak utorak sredu Äetvrtak petak subotu" ## Topics bignumtopic = "Ostale zanimljive aktivnosti:" othernumtopic = "Ostale zanimljivosti" latesttopic = "Poslednjih nekoliko topika" activetimestopic = "Intervali sa najviÅ¡e aktivnisti" activenickstopic = "Najaktivniji korisnici" activenickbyhourtopic = "Najaktivniji korisnici po satu" mostwordstopic = "NajÄešće upotrebljivane reÄi" referencetopic = "NajÄešće pomenut nadimak" smileytopic = "Smajliji :o)" karmatopic = "[:channel] karma" urlstopic = "NajÄešće pomenuta Internet adresa" chartstopic = "[:channel] MuziÄke liste" notopic = "Na ovom kanalu niko nije postavio topik" mostnickstopic = "Korisnici sa najviÅ¡e nadimaka" bylinetopic = "[:date] od [:nick] u [:time]" dailyactivitytopic = "Aktivnosti po danu (poslednjih [:n] dana)" activegenderstopic = "NajÄešći pol" ## Other text totallines = "Ukupan broj redova: [:lines]." totalnicks = "Usput budi reÄeno, bilo je joÅ¡ [:totalnicks] drugih nadimaka." totaltopic = "Topik je postavan [:total] puta." nick = "Nadimak" names = "Pominjana imena" url = "URL" numberlines = "Broj redova" randquote = "NasumiÄni citat" userpic = "Slika korisnika" nottop = "Nisu mogli da uÄ‘u u grupu od 35 najaktivnijih:" word = "ReÄ" numberuses = "Broj korisnika" show_words = "Broj reÄi" show_time = "Kada?" show_wpl = "ReÄi po redu" show_cpl = "Slova po redu" show_lastseen = "Poslednji put viÄ‘en" lastused = "Zadnji upotrebljen od" smiley = "Smajli" karma = "Karma" goodkarma = "Dobra karmao d" badkarma = "LoÅ¡a karma od" lastseen1 = "juÄe" lastseen2 = "pre [:days] dana" today = "danas" pagetitle1 = "[:channel] @ [:network] statistike napravio [:maintainer]" pagetitle2 = "Statistika je obnovljena u" pagetitle3 = "Za vreme ovog [:days]-dnevnog perioda, pojavilo se ukupno [:nicks] razliÄitih nadimaka na [:channel]." stats_gen_by = "Statistike generisao [:pisg_url] v[:version]" author = "pisg od autora [:author_url] i ostalih" stats_gen_in = "Statistike izraÄ‘ene za [:time]" hours = "Äasova" minutes = "minuta" seconds = "sekundi" and = "i" names1 = "imena" names2 = "ime" gender = "Pol" gender_f = "Žensko" gender_m = "MuÅ¡ko" gender_b = "Bot" song = "Pesma" numberplayed = "Koliko Äesto puÅ¡tana" playedby = "Poslednji je pustio" # Mouse-over titles pisghomepage = "Idi na pisg stranicu" authorhomepage = "Idi na autorovu stranicu" newwindow = "Otvara u novom prozoru:" mailto = "E-poÅ¡ta"
### Albanian mostop1 = "[:nick] dhuroi [:ops] OP në kanal..." mostop2 = "[:nick] ishte gjithashtu i sjellshëm: [:ops] OP nga [:ai:ajo:]." mostop3 = "E çuditshme, asnjë OP nuk u dha në [:channel]!" mostdeop1 = "[:nick] është polici i kanalit me [:deops] DEOP-erime." mostdeop2 = "[:nick] DEOP-eroi [:deops] përdorues." mostdeop3 = "Wow, nuk u dha asnjë OP në [:channel]!" mostvoice1 = "[:nick] dhuroi [:voices] VOICE në kanal..." mostvoice2 = "[:nick] ishte gjithashtu i sjellshëm: [:voices] VOICE nga [:ai:ajo:]." mostvoice3 = "E çuditshme, nuk është dhënë asnjë VOICE në [:channel]!" mostdevoice1 = "[:nick] i pëlqen të heqi VOICE të tjerëve, [:devoices] DEVOICES." mostdevoice2 = "[:nick] ishte afër të sipërpërmendurit, i hoqi VOICE [:devoices] përdoruesve." mostdevoice3 = "Nuk ndodhi asnjë DEVOICE në [:channel]!" mosthalfop1 = "[:nick] Dhuroi [:halfops] HALFOPS në kanal..." mosthalfop2 = "[:nick] ishte gjithashtu shumë i sjellshëm: [:halfops] HALFOP nga [:ai:ajo:]." mosthalfop3 = "E çuditshme, nuk është dhënë asnjë HALFOP në [:channel]!" mostdehalfop1 = "[:nick] është polici i kanalit me [:dehalfops] DEHALFOP." mostdehalfop2 = "[:nick] i hoqi HALFOP [:dehalfops] përdoruesve." mostdehalfop3 = "Wow, nuk u dha asnjë HALFOP në [:channel]!" action1 = "[:nick] na tregon gjithmonë çfarë [:ai:ajo:] është duke bërë me: [:actions] veprime!" action2 = "Gjithashtu, [:nick] na tregon çfarë bën me [:actions] veprime." action3 = "Asnjë veprim në [:channel]!" actiontext = "Përshembull, si ky:
     [:line]" question1 = "A është [:nick] budalla apo vetëm pyet? [:per]% e rreshtave përmbanin një pyetje!" question2 = "[:nick] nuk dinte kush e di se çfarë as ai. [:per]% e rreshtave të tij/saj ishin pyetje." question3 = "Asnjëri nuk bëri pyetje këtu; a thua janë të gjithë gjeni në këtë kanal?" shout1 = "Ai që bërtiste më shumë ishte [:nick], që ulëriti [:per]% të kohës!" shout2 = "Një tjetërgërthitës ishte [:nick], ulëriti [:per]% të kohës!" shout3 = "Wow, asnjë nuk bërtiti." allcaps1 = "Më duket se tasti Shift i [:nick] ka ngecur: [:per]% të kohës së [:tij:saj:] shkruajti me GËRMA TË MËDHA." allcaps2 = "[:nick] vetëm sa harroi të çaktivizojë Caps-Lock e [:tij:saj:]. [:Ai:Ajo:] shkruajti ME TË MADHE [:per]% të kohës." allcaps3 = "Të gjithë e kishin nën kontroll tastin Caps-Lock. :)" allcapstext = "Përshembull, si kjo:
     [:line]" violent1 = "[:nick] është një person i dhunshëm. [:Ai:Ajo:] sulmoi të tjerët [:attacks] herë." violent2 = "Sido që të jetë, edhe [:nick] nuk i kontrollon dot sulmet e [:tij:saj:]. [:Ai:Ajo:] ngacmoi të tjerët [:attacks] herë." violent3 = "Asnjëri nuk ngacmoi të tjerët. Çdokush qe miqësor." violenttext = "Përshembull, si kjo:
     [:line]" attacked1 = "I gjori [:nick], asnjëri nuk e pëlqen. [:Ai:Ajo:] u sulmua [:attacks] herë." attacked2 = "[:nick] ngjan të jetë i padëshiruar gjithashtu. [:Ai:Ajo:] u ngacmua [:attacks] herë." attackedtext = "Përshembull, si kjo:
     [:line]" gotkick1 = "[:nick] nuk qe shumë popullor, mori shqelma(kicked) [:kicks] herë!" gotkick2 = "[:nick] ngjan të ketë qenë i urryer gjithashtu: mori [:kicks] dëbime." kicktext = "Përshembull, si ky:
     [:line]" joins = "[:nick] nuk dinte ç'të bënte, të ikte apo të rrinte. [:joins] hyrje të raportuara në këtë periudhë!" kick1 = "[:nick] është një OP i çmendur(apo vetëm i drejtë?), ka përzënë [:kicked] person/a!" kick2 = "[:nick] e ndjek pas, zboi [:kicked] person/a." kick3 = "Paska operatorë të mirë këtu, asnjëri nuk ka marrë shqelma!" words1 = "[:nick] shkruajti një total prej [:words] fjalësh!" words2 = "[:nick] e ndjek pas, nuk foli dhe aq shume: [:words] fjalë." words3 = "Asnjeri nuk foli... Kanal i çuditshëm..." mono1 = "[:nick] flet shumë me vetveten. [:Ai:Ajo:] shkruajti mbi 5 herë nga një rresht [:monos] herë!" mono2 = "Një i vetmuar tjetër ishte [:nick], që qëlloi të fliste vetëm [:monos] herë." wpl1 = "[:nick] shkruajti mesatarisht [:wpl] fjalë për rresht." wpl2 = "Mesatarja e kanalit ishte [:avg] fjalë për rresht." long1 = "[:nick] shkruajti rreshtat më të gjatë, mesatarisht [:letters] shkronja për rresht." long2 = "Mesatarja e [:channel] ishte [:avg] gërma për rresht." short1 = "[:nick] shkruajti rreshtat më të shkurtër, mesatarisht [:letters] gërma për rresht." short2 = "Edhe [:nick] ishte përtac, gjithashtu, mesatarisht [:letters] gërma." foul1 = "[:nick] ishte llapazan. [:per]% e fjalëve ishin të tepërta." foul2 = "[:nick] gjithashtu mërzit të tjerët, [:per]% të kohës." foul3 = "Asnjëri nuk foli keq në [:channel]! Shumë përjashtime?" foultext = "Përshembull, si kjo:
     [:line]" smiles1 = "[:nick] lumturon botën. [:per]% e rreshtave përmbante buzëqeshje. :)" smiles2 = "As [:nick] nuk është i mërzitur, duke buzëqeshur [:per]% të kohës." smiles3 = "Asnjeri nuk buzëqeshi në [:channel]! Gëzohuni djem dhe vajza!" sad1 = "[:nick] ngjan i mërzitur për momentin: [:per]% e rreshtave përmbante mërzitje. :(" sad2 = "Edhe [:nick] është i mërzitur, duke u qarë [:per]% të kohës." sad3 = "Asnjeri nuk është i mërzitur në [:channel]! Sa kanal i qeshur! :-)" month = "Janar Shkurt Mars Prill Maj Qershor Korrik Gusht Shtator Tetor Nëntor Dhjetor" day = "Dielën, Hënën, Martën, Mërkurën, Enjten, Premten, Shtunën," ## Topics bignumtopic = "Shifra të mëdha" othernumtopic = "Statistika të tjera" latesttopic = "Tema e fundit" activetimestopic = "Periudhat më aktive" activenickstopic = "Personat më aktivë" activenickbyhourtopic = "Më aktivët sipas orës" mostwordstopic = "Fjalët më të përdorshme" referencetopic = "Më të përmendurit" urlstopic = "Adresat më të përmendura" notopic = "Ky kanal nuk ka patur asnjëherë ndonjë Temë." mostnickstopic = "Personat me më shumë nofka" bylinetopic = "[:date] nga [:nick] në [:time]" dailyactivitytopic = "Veprimtaria ditore ([:n] ditët e fundit)" smileytopic = "Buzëqeshje :-)" chartstopic = "[:channel] Renditja Muzikore" karmatopic = "karma e [:channel]" activegenderstopic = "Gjinia më aktive" ## Other text totallines = "Numri i përgjithshëm i rreshtave: [:lines]." totalnicks = "Meqë ra fjala, pati [:totalnicks] nofka të tjera." totaltopic = "Tema është vendosur [:total] herë." nick = "Nofka" names = "Emrat e Përdorur" url = "URL" numberlines = "Numrat e Rreshtave" randquote = "Citim i rastit" userpic = "Foto" nottop = "Këta nuk arritën të dalin në 'tabelë të nderit':" word = "Fjalë" numberuses = "Numri i Përdoruesve" show_words = "Numri i Fjalëve" show_time = "Kur?" show_wpl = "Fjalë për Rresht" show_cpl = "Gërma për Rresht" show_lastseen = "Parë së fundi" lastused = "I përdorur së fundi nga" lastseen1 = "[:days] ditë më parë" lastseen2 = "[:days] ditë më parë" today = "Sot" pagetitle1 = "Statistikat e [:channel] @ [:network] [:maintainer]" pagetitle2 = "Të dhënat u nxorrën të " pagetitle3 = "Gjatë këtyre [:days] ditëve raportimi, një total prej [:nicks] nofkash të ndryshme u prezantuan në [:channel]." stats_gen_by = "Statistikat, nxjerrë me [:pisg_url] v[:version]" author = "pisg nga [:author_url] dhe të tjerë" stats_gen_in = "Statistikat, nxjerrë në [:time]" hours = "orë" minutes = "minuta" seconds = "sekonda" and = "dhe" names1 = "emrat" names2 = "emri" karma = "Karma" badkarma = "Karma e keqe nga" goodkarma = "Karma e mirë nga" smiley = "Buzëqeshje" gender = "Gjinia" gender_b = "Bot" gender_f = "Femër" gender_m = "Mashkull" numberplayed = "Sa shpesh është luajtur" song = "Kënga" playedby = "Luajtur së fundi nga" # Mouse-over titles pisghomepage = "Vizito faqen e pisg" authorhomepage = "Shko tek faqja e autorit" newwindow = "Hape në dritare të re:" mailto = "Dërgoi një email"
pisg-0.73/modules/0000775000076400007650000000000011705647720012523 5ustar wadewadepisg-0.73/modules/Pisg.pm0000774000076400007650000005004011705647720013764 0ustar wadewadepackage Pisg; # Documentation(POD) for this module is found at the end of the file. # Copyright (C) 2001-2005 - morten@wtf.dk # Copyright (C) 2003-2006 Christoph Berg # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA use strict; $^W = 1; sub new { my $type = shift; my %args = @_; my $self = { override_cfg => $args{override_cfg}, use_configfile => $args{use_configfile}, search_path => $args{search_path}, chans => [], users => {}, cfg => {}, tmps => {}, }; # Set the default configuration settings. get_default_config_settings($self); # Import common functions in Pisg::Common require Pisg::Common; Pisg::Common->import(); bless($self, $type); return $self; } sub run { my $self = shift; print "pisg v$self->{cfg}->{version} - Perl IRC Statistics Generator\n\n" unless ($self->{cfg}->{silent}); # Init the configuration file (aliases, ignores, channels, etc) my $r; if ($self->{use_configfile}) { foreach my $c ($self->{cfg}->{configfile}, $self->{search_path} . "/$self->{cfg}->{configfile}") { if (open(CONFIG, $c)) { $self->{cfg}->{configfile} = $c; print "Using config file: $self->{cfg}->{configfile}\n\n" unless ($self->{cfg}->{silent}); $r = $self->init_config(\*CONFIG); last; } else { print STDERR "Warning: $c: $!\n\n" if -e $c; } } } # Get translations from langfile $self->get_language_templates(); # Parse any channels in statements $self->parse_channels(); # Optionaly parse the channel we were given in override_cfg. $self->do_channel() if (!$self->{cfg}->{chan_done}{$self->{cfg}->{channel}}); } sub get_default_config_settings { my $self = shift; # This is all the default settings of pisg. They can be overriden by the # pisg.cfg file, or by using the override_cfg argument to the new # constructor. $self->{cfg} = { channel => '', logtype => 'Logfile', logfile => [], format => '', network => 'SomeIRCNet', outputfile => 'index.html', outputtag => '', maintainer => 'MAINTAINER', pagehead => 'none', pagefoot => 'none', configfile => 'pisg.cfg', imagepath => '', imageglobpath => '', defaultpic => '', logdir => [], nfiles => 0, lang => 'EN', langfile => 'lang.txt', cssdir => 'layout/', colorscheme => 'default', altcolorscheme => 'none', logprefix => '', logsuffix => '', silent => 0, cachedir => '', userpics => 'y', # Colors / Layout hicell => '#BABADD', # FIXME hicell2 => '#CCCCCC', # FIXME picwidth => '', picheight => '', pic_v_0 => 'blue-v.png', pic_v_6 => 'green-v.png', pic_v_12 => 'yellow-v.png', pic_v_18 => 'red-v.png', pic_h_0 => 'blue-h.png', pic_h_6 => 'green-h.png', pic_h_12 => 'yellow-h.png', pic_h_18 => 'red-h.png', piclocation => '.', # Stats settings showactivetimes => 1, showactivenicks => 1, showbignumbers => 1, showtopics => 1, showlinetime => 0, showwordtime => 0, showlines => 1, showtime => 1, showwords => 0, showwpl => 0, showcpl => 0, showlastseen => 1, showlegend => 1, showkickline => 1, showactionline => 1, showfoulline => 0, showfouldecimals => 1, showshoutline => 1, showviolentlines => 1, showrandquote => 1, showmuw => 1, showmrn => 1, showsmileys => 0, showkarma => 0, showmru => 1, showcharts => 0, showops => 1, showvoices => 0, showhalfops => 0, showmostnicks => 0, showactivegenders => 0, showmostactivebyhour => 0, showmostactivebyhourgraph => 1, showonlytop => 0, # Less important things timeoffset => '+0', minquote => 25, maxquote => 65, quotewidth => 80, bignumbersthreshold => 'sqrt', wordlength => 5, dailyactivity => 0, activenicks => 25, activenicks2 => 30, activenicksbyhour => 10, topichistory => 3, urlhistory => 5, chartshistory => 5, nickhistory => 5, smileyhistory => 10, karmahistory => 5, wordhistory => 10, mostnickshistory => 5, mostnicksverbose => 1, nicklimit => 10, nicktracking => 0, charset => 'iso-8859-1', logcharset => '', logcharsetfallback => '', # sorting sortbywords => 0, # Misc settings foulwords => 'ass fuck bitch shit scheisse scheiße kacke arsch ficker ficken schlampe', violentwords => 'slaps beats smacks', chartsregexp => '(?:is )?(?:np:|(?:now )?playing:? |listening to:? )(?:MPEG stream from)?\s*(.*)', ignorewords => '', noignoredquotes => 0, tablewidth => 574, regexpaliases => 0, botnicks => '', # Needed for DCpp format (non-irc) statsdump => '', # Debug option modules_dir => '', # set in get_cmdline_options cchannels => '', # set in get_cmdline_options version => "0.73" }; # This enables us to use the search_path in other modules $self->{cfg}->{search_path} = $self->{search_path}; # Parse the optional overriden configuration variables foreach my $key (keys %{$self->{override_cfg}}) { if ($self->{override_cfg}->{$key}) { unless (defined($self->{cfg}->{$key})) { print STDERR "Warning: No such configuration option: -cfg $key\n"; next; } $self->{cfg}->{$key} = $self->{override_cfg}->{$key}; } } } sub get_language_templates { my $self = shift; open(FILE, $self->{cfg}->{langfile}) or open (FILE, $self->{search_path} . "/$self->{cfg}->{langfile}") or die("$0: Unable to open language file($self->{cfg}->{langfile}): $!\n"); while (my $line = ) { next if ($line =~ /^#/); if ($line =~ //i) { # Found start tag, setting the current language my $current_lang = uc($1); $self->{tmps}->{$current_lang}{lang_charset} = lc($2); while () { next if ($_ =~ /^#/); last if ($_ =~ /<\/lang>/i); # Get 'template = "Text"' in language file: if ($_ =~ /^(\w+)\s*=\s*"(.*)"\s*$/) { warn "duplicate translation $1 -> $2" if $self->{tmps}->{$current_lang}{$1} and !$self->{cfg}->{silent}; $self->{tmps}->{$current_lang}{$1} = $2; } } } } close(FILE); } sub init_config { my $self = shift; my $fh = shift; while (my $line = <$fh>) { next if ($line =~ /^\s*#/); chomp $line; if ($line =~ //) { my $nick; if ($line =~ /\bnick=(["'])(.+?)\1/) { $nick = $2; add_alias($nick, $nick); } else { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: No nick specified\n"; next; } if ($line =~ /\balias=(["'])(.+?)\1/) { my @thisalias = split(/\s+/, lc($2)); foreach (@thisalias) { if ($self->{cfg}->{regexpaliases} and /[\|\[\]\{\}\(\)\?\+\.\*\^\\]/) { add_aliaswild($nick, $_); } elsif (not $self->{cfg}->{regexpaliases} and s/\*/\.\*/g) { # quote it if it is a wildcard s/([\|\[\]\{\}\(\)\?\+\^\\])/\\$1/g; add_aliaswild($nick, $_); } else { add_alias($nick, $_); } } } if ($line =~ /\bpic=(["'])(.+?)\1/) { $self->{users}->{userpics}{$nick} = $2; } if ($line =~ /\bbigpic=(["'])(.+?)\1/) { $self->{users}->{biguserpics}{$nick} = $2; } if ($line =~ /\blink=(["'])(.+?)\1/) { $self->{users}->{userlinks}{$nick} = $2; } if ($line =~ /\bignore=(["'])Y\1/i) { add_ignore($nick); } if ($line =~ /\bsex=(["'])([MmFfBb])\1/) { $self->{users}->{sex}{$nick} = lc($2); } } elsif ($line =~ //) { if ($line =~ /\burl=(["'])(.+?)\1/) { my $url = $2; if ($line =~ /ignore="Y"/i) { add_url_ignore($url); } } else { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: No URL specified\n"; } } elsif ($line =~ //) { my $settings = $1; if ($settings !~ /=["'](.*)["']/ || $settings =~ /(\w)>/ ) { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: Missing or wrong quotes near $1\n"; } while ($settings =~ s/[ \t]([^=]+?)=(["'])(.*?)\2//) { my $var = lc($1); my $val = $3; $var =~ s/ //; # Remove whitespace if (!defined($self->{cfg}->{$var})) { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: No such configuration option: '$var'\n"; next; } unless (($self->{cfg}->{$var} eq $val) || $self->{override_cfg}->{$var}) { $self->{cfg}->{$var} = $val; } } } elsif ($line =~ //i) { my ($channel, $settings, $tmp) = ($2, $3, {}); $tmp->{$channel}->{channel} = $channel; $self->{cfg}->{chan_done}{$self->{cfg}->{channel}} = 1; # don't parse channel in $self->{cfg}->{channel} if a channel statement is present while ($settings =~ s/\s([^=]+)=(["'])(.*?)\2//) { my $var = lc($1); my $val = $3; if ($var eq "logdir" || $var eq "logfile") { push(@{$tmp->{$channel}{$var}}, $val); } else { $tmp->{$channel}{$var} = $val; } } while (<$fh>) { next if /^\s*#/; if ($_ =~ /<\/*channel>/i) { push @{ $self->{chans} }, $tmp; last; } if ($_ =~ /^\s*(\w+)\s*=\s*(["'])(.*?)\2/) { my $var = lc($1); my $val = $3; unless ((($var eq "logdir" || $var eq "logfile") && scalar(@{$self->{override_cfg}->{$var}}) > 0) || (($var ne "logdir" && $var ne "logfile") && $self->{override_cfg}->{$var})) { if($var eq "logdir" || $var eq "logfile") { push @{$tmp->{$channel}{$var}}, $val; } else { $tmp->{$channel}{$var} = $val; } } } elsif ($_ !~ /^$/) { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: Unrecognized line: $_"; } } } elsif ($line =~ //) { my $include_cfg = $2; my $backup_cfg = $self->{cfg}->{configfile}; $self->{cfg}->{configfile} = $include_cfg; my $r; foreach my $c ($self->{cfg}->{configfile}, $self->{search_path} . "/$self->{cfg}->{configfile}") { if (open(INCLUDE, $c)) { $self->{cfg}->{configfile} = $c; $r = $self->init_config(\*INCLUDE); last; } else { print STDERR "Warning: $backup_cfg, line $.: $c: $!\n" if -e $c; } } print "Included config file: $self->{cfg}->{configfile}\n\n" if ($r && !$self->{cfg}->{silent}); print STDERR "Warning: $backup_cfg, line $.: $self->{cfg}->{configfile} not found\n" if (!$r); $self->{cfg}->{configfile} = $backup_cfg; } elsif ($line =~ /<(\w+)?.*[^>]$/) { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: Missing end on element <$1 (probably multi-line?)\n"; } elsif ($line =~ /\S/) { $line =~ s/\n//; print STDERR "Warning: $self->{cfg}->{configfile}, line $.: Unrecognized line: $line\n"; } } close($fh); } sub init_pisg { my $self = shift; my $timestamp = time(); $self->{cfg}->{start} = time(); if ($self->{cfg}->{timeoffset} =~ /\+(\d+)/) { # We must plus some hours to the time $timestamp += 3600 * $1; # 3600 seconds per hour } elsif ($self->{cfg}->{timeoffset} =~ /-(\d+)/) { # We must remove some hours from the time $timestamp -= 3600 * $1; # 3600 seconds per hour } $self->{cfg}->{timestamp} = $timestamp; # convert wordlists $self->{cfg}->{foulwords} = wordlist_regexp($self->{cfg}->{foulwords}, $self->{cfg}->{regexpaliases}); $self->{cfg}->{ignorewords} = wordlist_regexp($self->{cfg}->{ignorewords}, $self->{cfg}->{regexpaliases}); $self->{cfg}->{violentwords} = wordlist_regexp($self->{cfg}->{violentwords}, $self->{cfg}->{regexpaliases}); # Add trailing slash when it's not there.. $self->{cfg}->{imagepath} =~ s/([^\/])$/$1\//; # Set ImageGlobPath default $self->{cfg}->{imageglobpath} ||= $self->{cfg}->{imagepath}; $self->{cfg}->{imageglobpath} =~ s/([^\/])$/$1\//; # Set number of picture columns to show if ($self->{cfg}->{userpics} =~ /^n/i) { $self->{cfg}->{userpics} = 0; } elsif ($self->{cfg}->{userpics} =~ /^y/i) { $self->{cfg}->{userpics} = 1; } elsif ($self->{cfg}->{userpics} !~ /^\d+$/) { print STDERR "Warning: $self->{cfg}->{configfile}, line $.: Invalid UserPics setting\n"; } unless ($self->{cfg}->{silent}) { print "Statistics for channel $self->{cfg}->{channel} \@ $self->{cfg}->{network} by $self->{cfg}->{maintainer}\n\n"; } } sub do_channel { my $self = shift; if (!$self->{cfg}->{channel}) { print STDERR "No channels defined.\n"; } elsif ((!@{$self->{cfg}->{logfile}}) && (!@{$self->{cfg}->{logdir}})) { print STDERR "No logfile or logdir defined for " . $self->{cfg}->{channel} . "\n"; } elsif (!$self->{cfg}->{format}) { print STDERR "No format defined for $self->{cfg}->{channel}.\n"; } else { $self->init_pisg(); # Init some general things store_aliases(); # Save the aliases so we can restore them # later, we don't want to add the aliases # for this channel to the next channel # Pick our stats generator. my $analyzer; eval <<_END; use Pisg::Parser::$self->{cfg}->{logtype}; \$analyzer = new Pisg::Parser::$self->{cfg}->{logtype}( { cfg => \$self->{cfg}, users => \$self->{users} } ); _END if ($@) { print STDERR "Could not load stats analyzer for '$self->{cfg}->{logtype}': $@\n"; return undef; } my $stats = $analyzer->analyze(); $self->{cfg}->{analyzer} = $analyzer; # we need the parser in _format_line # Initialize HTMLGenerator object my $generator; eval <<_END; use Pisg::HTMLGenerator; \$generator = new Pisg::HTMLGenerator( cfg => \$self->{cfg}, stats => \$stats, users => \$self->{users}, tmps => \$self->{tmps} ); _END if ($@) { print STDERR "Could not load stats generator (Pisg::HTMLGenerator): $@\n"; return undef; } # Create our HTML page if the logfile has any data. if (defined $stats) { if ($stats->{parsedlines} > 0) { foreach my $lang (split /\s*,\s*/, uc $self->{cfg}->{lang}) { $lang =~ s/-/_/g; # PT_BR was called PT-BR before die sprintf "No such language: %s\n", $_ unless $self->{tmps}->{$lang}; $generator->create_output($lang); } } else { print STDERR <<_END unless $self->{cfg}->{silent}; No parseable lines found in logfile ($stats->{totallines} total lines). Skipping. -> You might be using the wrong format. -> A common error is that the logs do not contain timestamps for each line. _END } } restore_aliases(); $self->{cfg}->{chan_done}{$self->{cfg}->{channel}} = 1; } } sub parse_channels { my $self = shift; my %origcfg = %{ $self->{cfg} }; # make a list of channels to do my @chanlist; if (scalar @ {$self->{cfg}->{cchannels} } > 0) { foreach my $channel (@{ $self->{cfg}->{cchannels} }) { my $hits = 0; foreach ( @{ $self->{chans} }) { my $chan = (keys %{ $_ })[0]; if (lc($channel) eq lc($chan)) { push @chanlist, $_; $hits++; } } if ($hits < 1) { print STDERR "Channel $channel not in config file, ignoring\n"; } } } else { push @chanlist, $_ foreach (@{ $self->{chans} }); } foreach my $channel (@chanlist) { foreach my $chan (keys %{ $channel }) { # import channel specific config $self->{cfg}->{$_} = $channel->{$chan}->{$_} foreach (keys %{ $channel->{$chan} }); } $self->do_channel(); $origcfg{chan_done} = $self->{cfg}->{chan_done}; %{ $self->{cfg} } = %origcfg; } } 1; __END__ =head1 NAME Pisg - Perl IRC Statistics Generator main module =head1 SYNOPSIS use Pisg; $pisg = new Pisg( use_configfile => '1', override_cfg => { network => 'MyNetwork', format => 'eggdrop' } ); $pisg->run(); =head1 DESCRIPTION C is a statistic generator for IRC logfiles or the like, delivering the results in a HTML page. =head1 CONSTRUCTOR =over 4 =item new ( [ OPTIONS ] ) This is the constructor for a new Pisg object. C are passed in a hash like fashion, using key and value pairs. Possible options are: B - When set to 1, pisg will look up it's channels in it's configuration file, defined by the configuration option 'configfile'. B - This defines whichever configuration variables you want to override from the configuration file. If you set use_configfile to 0, then you'll have to set at least channel and logfile here. B - This defines an optional search path. It's used when you want to hardcode an alternative path where pisg should look after its language and config file. =back =head1 AUTHOR Morten Brix Pedersen =head1 COPYRIGHT Copyright (C) 2001 Morten Brix Pedersen. All rights resereved. This program is free software; you can redistribute it and/or modify it under the terms of the GPL, license is included with the distribution of this file. =cut pisg-0.73/modules/Pisg/0000775000076400007650000000000011705647720013425 5ustar wadewadepisg-0.73/modules/Pisg/HTMLGenerator.pm0000774000076400007650000024536411705647720016416 0ustar wadewadepackage Pisg::HTMLGenerator; # $Id: HTMLGenerator.pm,v 1.189 2007/09/07 23:17:23 df7cb Exp $ # # Copyright and license, as well as documentation(POD) for this module is # found at the end of the file. use strict; $^W = 1; # test for Text::Iconv my $have_iconv = 1; eval 'use Text::Iconv'; $have_iconv = 0 if $@; sub new { my $type = shift; my %args = @_; my $self = { cfg => $args{cfg}, stats => $args{stats}, users => $args{users}, tmps => $args{tmps}, topactive => {}, }; # Import common functions in Pisg::Common require Pisg::Common; Pisg::Common->import(); bless($self, $type); return $self; } sub create_output { # This subroutine calls all the subroutines which create their # individual stats. The name of the functions is somewhat saying - if # you don't understand it, most subs have a better explanation in the # sub itself. my $self = shift; $self->{cfg}->{lang} = shift; # save table width as multiplie files would just increase tablewidth my $tablewidth_original = $self->{cfg}->{tablewidth}; # remove old iconv if it exist as it could mess up recode. delete $self->{iconv} if $self->{iconv}; my $lang_charset = $self->{tmps}->{$self->{cfg}->{lang}}{lang_charset}; if($lang_charset and $lang_charset ne $self->{cfg}->{charset}) { if($have_iconv) { # convert from template charset to our $self->{iconv} = Text::Iconv->new($lang_charset, $self->{cfg}->{charset}); } else { print "Text::Iconv is not installed, skipping charset conversion of language templates\n" unless ($self->{cfg}->{silent}); } } $self->_topactive(); if($self->{cfg}->{bignumbersthreshold} =~ /^sqrt/) { $self->{cfg}->{bignumbersthreshold} = int(sqrt($self->{stats}->{topactive_lines})); } my $fname = $self->{cfg}->{outputfile}; $fname =~ s/\%t/$self->{cfg}->{outputtag}/g; $fname =~ s/\%l/$self->{cfg}->{lang}/g; print "Now generating HTML ($self->{cfg}->{lang}) in $fname...\n" unless ($self->{cfg}->{silent}); open (OUTPUT, "> $fname") or die("$0: Unable to open outputfile($fname): $!\n"); if ($self->{cfg}->{showlines}) { $self->{cfg}->{tablewidth} += 40; } if ($self->{cfg}->{showtime}) { $self->{cfg}->{tablewidth} += 40; } if ($self->{cfg}->{showlinetime}) { $self->{cfg}->{tablewidth} += 100; } if ($self->{cfg}->{showwordtime}) { $self->{cfg}->{tablewidth} += 100; } if ($self->{cfg}->{showwords}) { $self->{cfg}->{tablewidth} += 40; } if ($self->{cfg}->{showwpl}) { $self->{cfg}->{tablewidth} += 40; } if ($self->{cfg}->{showcpl}) { $self->{cfg}->{tablewidth} += 40; } if ($self->{cfg}->{userpics}) { $self->{cfg}->{tablewidth} += $self->{cfg}->{userpics} * ($self->{cfg}->{picwidth} || 60); } $self->{cfg}->{headwidth} = $self->{cfg}->{tablewidth} - 4; $self->_htmlheader(); $self->_pageheader() if ($self->{cfg}->{pagehead} ne 'none'); if ($self->{cfg}->{dailyactivity}) { $self->_activedays(); } if ($self->{cfg}->{showactivetimes}) { $self->_activetimes(); } if ($self->{cfg}->{showactivenicks}) { $self->_activenicks(); } if ($self->{cfg}->{showmostactivebyhour}) { $self->_mostactivebyhour(); } if ($self->{cfg}->{showbignumbers}) { $self->_headline($self->_template_text('bignumtopic')); _html("{cfg}->{tablewidth}\">"); # Needed for sections $self->_questions(); $self->_shoutpeople(); $self->_capspeople(); $self->_violent(); $self->_mostsmiles(); $self->_mostsad(); $self->_linelengths(); $self->_mostwords(); $self->_mostwordsperline(); _html("
"); # Needed for sections } if ($self->{cfg}->{showmostnicks}) { $self->_mostnicks(); } if ($self->{cfg}->{showactivegenders}) { $self->_activegenders(); } if ($self->{cfg}->{showmuw}) { $self->_mostusedword(); } if ($self->{cfg}->{showmrn}) { $self->_mostreferencednicks(); } if ($self->{cfg}->{showsmileys}) { $self->_smileys(); } if ($self->{cfg}->{showkarma}) { $self->_karma(); } if ($self->{cfg}->{showmru}) { $self->_mosturls(); } if ($self->{cfg}->{showcharts}) { $self->_charts(); } if ($self->{cfg}->{showbignumbers}) { $self->_headline($self->_template_text('othernumtopic')); _html("{cfg}->{tablewidth}\">"); # Needed for sections $self->_gotkicks(); $self->_mostkicks(); $self->_mostop() if $self->{cfg}->{showops}; $self->_mosthalfop() if $self->{cfg}->{showhalfops}; $self->_mostvoice() if $self->{cfg}->{showvoices}; $self->_mostactions(); $self->_mostmonologues(); $self->_mostjoins(); $self->_mostfoul(); _html("
"); # Needed for sections } if ($self->{cfg}->{showtopics}) { $self->_headline($self->_template_text('latesttopic')); _html("{cfg}->{tablewidth}\">"); # Needed for sections $self->_lasttopics(); _html("
"); # Needed for sections } my %hash = ( lines => $self->{stats}->{parsedlines} ); _html($self->_template_text('totallines', %hash) . "

"); $self->_pagefooter() if ($self->{cfg}->{pagefoot} ne 'none'); $self->_htmlfooter(); close(OUTPUT); # restore tablewidth $self->{cfg}->{tablewidth} = $tablewidth_original; } sub _htmlheader { my $self = shift; my %hash = ( network => $self->{cfg}->{network}, maintainer => $self->{cfg}->{maintainer}, days => $self->{stats}->{days}, nicks => scalar keys %{ $self->{stats}->{lines} } ); my $CSS; if($self->{cfg}->{colorscheme} =~ /([^\/.]+)\.[^\/]+$/) { # use external CSS file $CSS = "{cfg}->{colorscheme}\" />"; } elsif($self->{cfg}->{colorscheme} ne "none") { # read the chosen CSS file my $css_file = $self->{cfg}->{cssdir} . $self->{cfg}->{colorscheme} . ".css"; open(FILE, $css_file) or open (FILE, $self->{cfg}->{search_path} . "/$css_file") or die("$0: Unable to open stylesheet $css_file: $!\n"); { local $/; # enable "slurp" mode $CSS = ""; $CSS =~ s/\/\*/\/\* \*\//g; } close FILE; } # use alternate CSS file if($self->{cfg}->{altcolorscheme} ne "none" and $self->{cfg}->{altcolorscheme} =~ /[^\w]/) { foreach (split /\s+/, $self->{cfg}->{altcolorscheme}) { /([^\/.]+)\.[^\/]+$/; $CSS .= "\n"; } } my $title = $self->_template_text('pagetitle1', %hash); if($self->{cfg}->{colorscheme} ne "none") { _html( < $title $CSS
HTML } _html("$title
"); _html("
"); _html($self->_template_text('pagetitle2', %hash) . " " . $self->get_time()); _html("
" . $self->_template_text('pagetitle3', %hash) . "

"); } sub get_time { my $self = shift; my ($tday, %hash); my $month = $self->_template_text('month', %hash); my $day = $self->_template_text('day', %hash); my @month = split(" ", $month); my @day = split(" ", $day); # Get the Date from the users computer my $timezone = $self->{cfg}->{timeoffset} * 3600; my ($sec,$min,$hour,$mday,$mon,$year,$wday) = localtime(time+$timezone); $year += 1900; # Y2K Patch $min =~ s/^(.)$/0$1/; # Fixes the display of mins/secs below $sec =~ s/^(.)$/0$1/; # it displays 03 instead of 3 if ($hour > '23') { # Checks to see if it Midnight $hour = 12; # Makes it display the hour 12 $tday = "AM"; # Display AM } elsif($hour > '12') { # Get rid of the Military time and $hour -= 12; # put it into normal time $tday = "PM"; # If past Noon and before Midnight set } else { $tday = "AM"; # If it's past Midnight and before Noon } # set the time as AM # Use 24 hours pr. day if ($tday eq "PM" && $hour < '12') { $hour += 12; } return "$day[$wday] $mday $month[$mon] $year - $hour:$min:$sec"; } sub _htmlfooter { my $self = shift; my %hash; my $pisg_hp = $self->_template_text('pisghomepage'); $hash{pisg_url} = "pisg"; my $author_hp = $self->_template_text('authorhomepage'); $hash{author_url} = "Morten Brix Pedersen"; $hash{version} = $self->{cfg}->{version}; my $hours = $self->_template_text('hours'); my $mins = $self->_template_text('minutes'); my $secs = $self->_template_text('seconds'); my $and = $self->_template_text('and'); my $h = $self->{stats}->{processtime}{hours}; my $m = $self->{stats}->{processtime}{mins}; my $s = $self->{stats}->{processtime}{secs}; $hash{time} = "$h $hours $m $mins $and $s $secs"; my $stats_gen = $self->_template_text('stats_gen_by', %hash); my $author_text = $self->_template_text('author', %hash); my $stats_text = $self->_template_text('stats_gen_in', %hash); _html( < $stats_gen
$author_text
$stats_text HTML _html( sprintf( qq(), $self->{cfg}->{nfiles}, $self->{cfg}->{format}, $self->{cfg}->{lang}, $self->{cfg}->{langfile}, $self->{cfg}->{charset}, $self->{cfg}->{logcharset}, $self->{cfg}->{logcharsetfallback}, $self->{cfg}->{logprefix}, $self->{cfg}->{logsuffix}, $self->{cfg}->{nicktracking}, $self->{cfg}->{timeoffset} )); if($self->{cfg}->{colorscheme} ne "none") { _html( < HTML } } sub _headline { my $self = shift; my ($title) = (@_); _html( <
$title
HTML } sub _pageheader { my $self = shift; unless(open(PAGEHEAD, $self->{cfg}->{pagehead})) { warn("$0: Unable to open $self->{cfg}->{pagehead} for reading: $!\n"); return; } while () { chomp; _html($_); } close(PAGEHEAD); } sub _pagefooter { my $self = shift; unless(open(PAGEFOOT, $self->{cfg}->{pagefoot})) { warn("$0: Unable to open $self->{cfg}->{pagefoot} for reading: $!\n"); return; } while () { chomp; _html($_); } close(PAGEFOOT); } sub _activedays { # The most actives days on the channel my $self = shift; my $days = $self->{stats}->{days}; my $ndays = $self->{cfg}->{dailyactivity}; my $highest_value = 1; for (my $day = $days; $day > $days - $ndays ; $day--) { if (defined($self->{stats}->{day_lines}->[$day])) { if ($self->{stats}->{day_lines}->[$day] > $highest_value) { $highest_value = $self->{stats}->{day_lines}->[$day]; } } else { #there are only $days - $day days :) $ndays = $days - $day; last; } } my %hash = ( n => $ndays ); $self->_headline($self->_template_text('dailyactivitytopic', %hash)); _html(""); for (my $day = $days - $ndays + 1; $day <= $days ; $day++) { my $lines = $self->{stats}->{day_lines}[$day]; _html(""); } _html(""); for (my $day = $ndays - 1; $day >= 0 ; $day--) { _html(""); } _html("
$lines
"); for (my $time = 4; $time >= 0; $time--) { if (defined($self->{stats}->{day_times}[$day][$time])) { my $size = int(($self->{stats}->{day_times}[$day][$time] / $highest_value) * 100); my $image = "pic_v_".$time*6; $image = $self->{cfg}->{$image}; _html("{cfg}->{piclocation}/$image\" width=\"15\" height=\"$size\" alt=\"$size\" title=\"$size\" />
") if $size; } } _html("
$day
"); if($self->{cfg}->{showlegend} == 1) { $self->_legend(); } } sub _activetimes { # The most actives times on the channel my $self = shift; my (%output); $self->_headline($self->_template_text('activetimestopic')); my @toptime = sort { $self->{stats}->{times}{$b} <=> $self->{stats}->{times}{$a} } keys %{ $self->{stats}->{times} }; my $highest_value = $self->{stats}->{times}{$toptime[0]}; for my $hour (sort keys %{ $self->{stats}->{times} }) { my $size = int(($self->{stats}->{times}{$hour} / $highest_value) * 100); my $percent = sprintf("%.1f", ($self->{stats}->{times}{$hour} / $self->{stats}->{parsedlines}) * 100); my $lines_per_hour = $self->{stats}->{times}{$hour}; my $image = "pic_v_".(int($hour/6)*6); $image = $self->{cfg}->{$image}; $output{$hour} = "$percent%
{cfg}->{piclocation}/$image\" width=\"15\" height=\"$size\" alt=\"$lines_per_hour\" title=\"$lines_per_hour\"/>" if $size; } _html(""); for ($b = 0; $b < 24; $b++) { $a = sprintf("%02d", $b); if (!defined($output{$a})) { _html(""); } else { _html($output{$a}); } } _html(""); # Remove leading zero $toptime[0] =~ s/^0//; for ($b = 0; $b < 24; $b++) { # Highlight the top time my $class = $toptime[0] == $b ? 'hirankc10center' : 'rankc10center'; _html(""); } _html("
0%
$b
"); if($self->{cfg}->{showlegend} == 1) { $self->_legend(); } } sub _activenicks { # The most active nicks (those who wrote most lines) my $self = shift; $self->_headline($self->_template_text('activenickstopic')); my $output = ""; $output .= "{cfg}->{tablewidth}\">"; $output .= ""; $output .= ""; $output .= "" if ($self->{cfg}->{showlines}); $output .= "" if ($self->{cfg}->{showtime}); $output .= "" if ($self->{cfg}->{showwords}); $output .= "" if ($self->{cfg}->{showwpl}); $output .= "" if ($self->{cfg}->{showcpl}); $output .= "" if ($self->{cfg}->{showlastseen}); $output .= "" if ($self->{cfg}->{showrandquote}); $output .= "\n"; my @active; my $nicks; if ($self->{cfg}->{sortbywords}) { @active = sort { $self->{stats}->{words}{$b} <=> $self->{stats}->{words}{$a} } keys %{ $self->{stats}->{words} }; $nicks = scalar keys %{ $self->{stats}->{words} }; } else { @active = sort { $self->{stats}->{lines}{$b} <=> $self->{stats}->{lines}{$a} } keys %{ $self->{stats}->{lines} }; $nicks = scalar keys %{ $self->{stats}->{lines} }; } if ($self->{cfg}->{activenicks} > $nicks) { $self->{cfg}->{activenicks} = $nicks; } for (my $c = 0; $c < $self->{cfg}->{activenicks}; $c++) { last unless $self->{cfg}->{userpics}; my $nick = $active[$c]; if ($self->{users}->{userpics}{$nick} or $self->{cfg}->{defaultpic}) { $output .= ""; last; } } $output .= "\n"; _html($output); undef $output; for (my $i = 0; $i < $self->{cfg}->{activenicks}; $i++) { my $c = $i + 1; my $nick = $active[$i]; my $visiblenick; my $randomline; if (not defined $self->{stats}->{sayings}{$nick}) { if ($self->{stats}->{actions}{$nick}) { $randomline = $self->{stats}->{actionlines}{$nick}; } else { $randomline = ""; } } else { $randomline = $self->{stats}->{sayings}{$nick}; } if ($randomline) { $randomline = $self->_format_line($randomline); } # Add a link to the nick if there is any and quote nick if ($self->{users}->{userlinks}{$nick}) { $visiblenick = $self->_format_word($self->{users}->{userlinks}{$nick}, $nick); } else { $visiblenick = $self->_format_word($nick); } my $style = $self->generate_colors($c); my $class = 'rankc'; if ($c == 1) { $class = 'hirankc'; } my $lastseen; if ($self->{cfg}->{showlastseen}) { $lastseen = $self->{stats}->{days} - $self->{stats}->{lastvisited}{$nick}; my %hash = ( days => $lastseen ); if ($lastseen == 0) { $lastseen = $self->_template_text('today'); } elsif ($lastseen == 1) { $lastseen = $self->_template_text('lastseen1', %hash); } else { $lastseen = $self->_template_text('lastseen2', %hash); } } _html(""); my $line = $self->{stats}->{lines}{$nick}; my $w = $self->{stats}->{words}{$nick} ? $self->{stats}->{words}{$nick} : 0; my $ch = $self->{stats}->{lengths}{$nick}; my $sex = $self->{users}->{sex}{$nick}; my $output = ""; $output .= ""; if ($self->{cfg}->{showlines}) { if ($self->{cfg}->{showlinetime}) { $output .= ""; } else { $output .= ""; } } $output .= "" if ($self->{cfg}->{showtime}); if ($self->{cfg}->{showwords}) { if ($self->{cfg}->{showwordtime}) { $output .= ""; } else { $output .= ""; } } $output .= "" if ($self->{cfg}->{showwpl}); $output .= "" if ($self->{cfg}->{showcpl}); $output .= "" if ($self->{cfg}->{showlastseen}); $output .= "" if ($self->{cfg}->{showrandquote}); _html($output); undef $output; if ($self->{cfg}->{userpics} && $i % $self->{cfg}->{userpics} == 0) { for my $ii (0 .. $self->{cfg}->{userpics} - 1) { last if $i + $ii >= $self->{cfg}->{activenicks}; $self->_user_pic($active[$i + $ii], $style); } } _html(""); } _html("
 " . $self->_template_text('nick') . "" . $self->_template_text('numberlines') . "" . $self->_template_text('show_time') . "" . $self->_template_text('show_words') . "" . $self->_template_text('show_wpl') . "" . $self->_template_text('show_cpl') . "" . $self->_template_text('show_lastseen') . "" . $self->_template_text('randquote') . "{cfg}->{userpics}\"" if ($self->{cfg}->{userpics} > 1); $output .= ">" . $self->_template_text('userpic') ."
$c"; # Hilight nick with gendercolors if ($sex and $sex eq 'm') { $output .= ""; } elsif ($sex and $sex eq 'f') { $output .= ""; } elsif ($sex and $sex eq 'b') { $output .= ""; } else { $output .= ""; } $output .= $visiblenick; $output .= "" . $self->_user_linetimes($nick,$active[0]) . "$line" . $self->_user_times($nick) . "" . $self->_user_wordtimes($nick,$active[0]) . "$w" . sprintf("%.1f", $w/$line) . "" . sprintf("%.1f", $ch/$line) . "$lastseen\"$randomline\"

"); # Almost as active nicks ('These didn't make it to the top..') my $toshow = $self->{cfg}->{activenicks2} - $self->{cfg}->{activenicks}; my $remain = $self->{cfg}->{activenicks} + $toshow; unless ($toshow > $nicks) { $remain = $self->{cfg}->{activenicks} + $self->{cfg}->{activenicks2}; if ($remain > $nicks) { $remain = $nicks; } if ($self->{cfg}->{activenicks} < $remain) { _html("
" . $self->_template_text('nottop') . ""); for (my $i = $self->{cfg}->{activenicks}; $i < $remain; $i++) { my $visiblenick; my $nick = $active[$i]; if ($i != $self->{cfg}->{activenicks} and ($i - $self->{cfg}->{activenicks}) % 5 == 0) { _html(""); } my $items; if ($self->{users}->{userlinks}{$nick}) { $visiblenick = $self->_format_word($self->{users}->{userlinks}{$nick}, $nick); } else { $visiblenick = $self->_format_word($nick); } if ($self->{cfg}->{sortbywords}) { $items = $self->{stats}->{words}{$active[$i]}; } else { $items = $self->{stats}->{lines}{$active[$i]}; } my $sex = $self->{users}->{sex}{$active[$i]}; my $output = ""; $output .= ""; _html($output); undef $output; } _html("
"; if ($sex and $sex eq 'm') { $output .= ""; } elsif ($sex and $sex eq 'f') { $output .= ""; } elsif ($sex and $sex eq 'b') { $output .= ""; } else { $output .= ""; } $output .= "$visiblenick ($items)"; $output .= "
"); } } my %hash; $hash{totalnicks} = $nicks - $remain; if ($hash{totalnicks} > 0) { _html("
" . $self->_template_text('totalnicks', %hash) . "
"); } } sub generate_colors { my $self = shift; my $c = shift; # if hicell or hicell2 is "", do not print the class as it could mess up the gendercode return "" if not (length $self->{cfg}->{hicell} and length $self->{cfg}->{hicell2}); my $h = $self->{cfg}->{hicell} or return "class=\"hicell\""; $h =~ s/^#//; $h = hex $h; my $h2 = $self->{cfg}->{hicell2} or return "class=\"hicell\""; $h2 =~ s/^#//; $h2 = hex $h2; my $f_b = $h & 0xff; my $f_g = ($h & 0xff00) >> 8; my $f_r = ($h & 0xff0000) >> 16; my $t_b = $h2 & 0xff; my $t_g = ($h2 & 0xff00) >> 8; my $t_r = ($h2 & 0xff0000) >> 16; my $blue = sprintf "%0.2x", abs int(((($t_b - $f_b) / $self->{cfg}->{activenicks}) * +$c) + $f_b); my $green = sprintf "%0.2x", abs int(((($t_g - $f_g) / $self->{cfg}->{activenicks}) * +$c) + $f_g); my $red = sprintf "%0.2x", abs int(((($t_r - $f_r) / $self->{cfg}->{activenicks}) * +$c) + $f_r); return "style=\"background-color: #$red$green$blue\""; } sub _html { my $html = shift; print OUTPUT "$html\n" or die "Could not write to disk: $!\n"; } sub _questions { # Persons who asked the most questions my $self = shift; my %qpercent; foreach my $nick (sort keys %{ $self->{stats}->{questions} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $qpercent{$nick} = sprintf("%.1f", ($self->{stats}->{questions}{$nick} / $self->{stats}->{lines}{$nick}) * 100); } } } my @question = sort { $qpercent{$b} <=> $qpercent{$a} } keys %qpercent; if (@question) { my %hash = ( nick => $question[0], per => $qpercent{$question[0]} ); my $text = $self->_template_text('question1', %hash); _html("$text"); if (@question >= 2) { my %hash = ( nick => $question[1], per => $qpercent{$question[1]} ); my $text = $self->_template_text('question2', %hash); _html("
$text"); } _html(""); } else { _html("" . $self->_template_text('question3') . ""); } } sub _shoutpeople { # The ones who speak with exclamation marks! my $self = shift; my %spercent; foreach my $nick (sort keys %{ $self->{stats}->{shouts} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $spercent{$nick} = sprintf("%.1f", ($self->{stats}->{shouts}{$nick} / $self->{stats}->{lines}{$nick}) * 100); } } } my @shout = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent; if (@shout) { my %hash = ( nick => $shout[0], per => $spercent{$shout[0]} ); my $text = $self->_template_text('shout1', %hash); _html("$text"); if (@shout >= 2) { my %hash = ( nick => $shout[1], per => $spercent{$shout[1]} ); my $text = $self->_template_text('shout2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('shout3'); _html("$text"); } } sub _capspeople { # The ones who speak ALL CAPS. my $self = shift; my %cpercent; foreach my $nick (sort keys %{ $self->{stats}->{allcaps} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $cpercent{$nick} = sprintf("%.1f", $self->{stats}->{allcaps}{$nick} / $self->{stats}->{lines}{$nick} * 100); } } } my @caps = sort { $cpercent{$b} <=> $cpercent{$a} } keys %cpercent; if (@caps) { my %hash = ( nick => $caps[0], per => $cpercent{$caps[0]}, line => $self->_format_line($self->{stats}->{allcaplines}{$caps[0]}) ); my $text = $self->_template_text('allcaps1', %hash); if($self->{cfg}->{showshoutline}) { my $exttext = $self->_template_text('allcapstext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@caps >= 2) { my %hash = ( nick => $caps[1], per => $cpercent{$caps[1]} ); my $text = $self->_template_text('allcaps2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('allcaps3'); _html("$text"); } } sub _violent { # They attacked others (words defined by $self->{cfg}->{violent}) my $self = shift; my @aggressors = sort { $self->{stats}->{violence}{$b} <=> $self->{stats}->{violence}{$a} } keys %{ $self->{stats}->{violence} }; @aggressors = $self->_istoponly(@aggressors); if(@aggressors) { my %hash = ( nick => $aggressors[0], attacks => $self->{stats}->{violence}{$aggressors[0]}, line => $self->_format_line($self->{stats}->{violencelines}{$aggressors[0]}) ); my $text = $self->_template_text('violent1', %hash); if($self->{cfg}->{showviolentlines}) { my $exttext = $self->_template_text('violenttext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@aggressors >= 2) { my %hash = ( nick => $aggressors[1], attacks => $self->{stats}->{violence}{$aggressors[1]} ); my $text = $self->_template_text('violent2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('violent3'); _html("$text"); } # They got attacked my @victims = sort { $self->{stats}->{attacked}{$b} <=> $self->{stats}->{attacked}{$a} } keys %{ $self->{stats}->{attacked} }; @victims = $self->_istoponly(@victims); if(@victims) { my %hash = ( nick => $victims[0], attacks => $self->{stats}->{attacked}{$victims[0]}, line => $self->_format_line($self->{stats}->{attackedlines}{$victims[0]}) ); my $text = $self->_template_text('attacked1', %hash); if($self->{cfg}->{showviolentlines}) { my $exttext = $self->_template_text('attackedtext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@victims >= 2) { my %hash = ( nick => $victims[1], attacks => $self->{stats}->{attacked}{$victims[1]} ); my $text = $self->_template_text('attacked2', %hash); _html("
$text"); } _html(""); } } sub _gotkicks { # The persons who got kicked the most my $self = shift; my @gotkick = sort { $self->{stats}->{gotkicked}{$b} <=> $self->{stats}->{gotkicked}{$a} } keys %{ $self->{stats}->{gotkicked} }; @gotkick = $self->_istoponly(@gotkick); if (@gotkick) { my %hash = ( nick => $gotkick[0], kicks => $self->{stats}->{gotkicked}{$gotkick[0]}, line => $self->_format_line($self->{stats}->{kicklines}{$gotkick[0]}) ); my $text = $self->_template_text('gotkick1', %hash); if ($self->{cfg}->{showkickline}) { my $exttext = $self->_template_text('kicktext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@gotkick >= 2) { my %hash = ( nick => $gotkick[1], kicks => $self->{stats}->{gotkicked}{$gotkick[1]} ); my $text = $self->_template_text('gotkick2', %hash); _html("
$text"); } _html(""); } } sub _mostjoins { my $self = shift; my @joins = sort { $self->{stats}->{joins}{$b} <=> $self->{stats}->{joins}{$a} } keys %{ $self->{stats}->{joins} }; @joins = $self->_istoponly(@joins); if (@joins) { my %hash = ( nick => $joins[0], joins => $self->{stats}->{joins}{$joins[0]} ); my $text = $self->_template_text('joins', %hash); _html("$text"); } } sub _mostwords { # The person who got words the most my $self = shift; my @words = sort { $self->{stats}->{words}{$b} <=> $self->{stats}->{words}{$a} } keys %{ $self->{stats}->{words} }; @words = $self->_istoponly(@words); if (@words) { my %hash = ( nick => $words[0], words => $self->{stats}->{words}{$words[0]} ); my $text = $self->_template_text('words1', %hash); _html("$text"); if (@words >= 2) { my %hash = ( oldnick => $words[0], nick => $words[1], words => $self->{stats}->{words}{$words[1]} ); my $text = $self->_template_text('words2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('words3'); _html("$text"); } } sub _mostkicks { # The person who kicked the most my $self = shift; my @kicked = sort { $self->{stats}->{kicked}{$b} <=> $self->{stats}->{kicked}{$a} } keys %{ $self->{stats}->{kicked} }; @kicked = $self->_istoponly(@kicked); if (@kicked) { my %hash = ( nick => $kicked[0], kicked => $self->{stats}->{kicked}{$kicked[0]} ); my $text = $self->_template_text('kick1', %hash); _html("$text"); if (@kicked >= 2) { my %hash = ( oldnick => $kicked[0], nick => $kicked[1], kicked => $self->{stats}->{kicked}{$kicked[1]} ); my $text = $self->_template_text('kick2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('kick3'); _html("$text"); } } sub _mostmonologues { # The person who had the most monologues (speaking to himself) my $self = shift; my @monologue = sort { $self->{stats}->{monologues}{$b} <=> $self->{stats}->{monologues}{$a} } keys %{ $self->{stats}->{monologues} }; @monologue = $self->_istoponly(@monologue); if (@monologue) { my %hash = ( nick => $monologue[0], monos => $self->{stats}->{monologues}{$monologue[0]} ); my $text = $self->_template_text('mono1', %hash); _html("$text"); if (@monologue >= 2) { my %hash = ( nick => $monologue[1], monos => $self->{stats}->{monologues}{$monologue[1]} ); my $text = $self->_template_text('mono2', %hash); _html("
$text"); } _html(""); } } sub _linelengths { # The person(s) who wrote the longest lines my $self = shift; my %len; foreach my $nick (sort keys %{ $self->{stats}->{lengths} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $len{$nick} = sprintf("%.1f", $self->{stats}->{lengths}{$nick} / $self->{stats}->{lines}{$nick}); } } } my @len = sort { $len{$b} <=> $len{$a} } keys %len; my $all_lines = 0; my $totallength; foreach my $nick (keys %{ $self->{stats}->{lines} }) { $all_lines += $self->{stats}->{lines}{$nick}; $totallength += $self->{stats}->{lengths}{$nick}; } my $totalaverage; if ($all_lines > 0) { $totalaverage = sprintf("%.1f", $totallength / $all_lines); } if (@len) { my %hash = ( nick => $len[0], letters => $len{$len[0]} ); my $text = $self->_template_text('long1', %hash); _html("$text
"); if (@len >= 2) { %hash = ( avg => $totalaverage ); $text = $self->_template_text('long2', %hash); _html("$text"); } else { _html(""); } } # The person(s) who wrote the shortest lines if (@len) { my %hash = ( nick => $len[$#len], letters => $len{$len[$#len]} ); my $text = $self->_template_text('short1', %hash); _html("$text
"); if (@len >= 2) { %hash = ( nick => $len[$#len - 1], letters => $len{$len[$#len - 1]} ); $text = $self->_template_text('short2', %hash); _html("$text"); } else { _html(""); } } } sub _mostfoul { my $self = shift; my %spercent; foreach my $nick (sort keys %{ $self->{stats}->{foul} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > 15) { my $dec = $self->{cfg}->{showfouldecimals}; $dec = 1 if($dec < 0); # default to 1 $spercent{$nick} = sprintf("%.${dec}f", $self->{stats}->{foul}{$nick} / $self->{stats}->{words}{$nick} * 100); } } } my @foul = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent; if (@foul) { my %hash = ( nick => $foul[0], per => $spercent{$foul[0]}, line => $self->_format_line($self->{stats}{foullines}{$foul[0]}), ); my $text = $self->_template_text('foul1', %hash); if($self->{cfg}->{showfoulline}) { my $exttext = $self->_template_text('foultext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@foul >= 2) { my %hash = ( nick => $foul[1], per => $spercent{$foul[1]} ); my $text = $self->_template_text('foul2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('foul3'); _html("$text"); } } sub _mostsad { my $self = shift; my %spercent; foreach my $nick (sort keys %{ $self->{stats}->{frowns} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $spercent{$nick} = sprintf("%.1f", $self->{stats}->{frowns}{$nick} / $self->{stats}->{lines}{$nick} * 100); } } } my @sadface = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent; if (@sadface) { my %hash = ( nick => $sadface[0], per => $spercent{$sadface[0]} ); my $text = $self->_template_text('sad1', %hash); _html("$text"); if (@sadface >= 2) { my %hash = ( nick => $sadface[1], per => $spercent{$sadface[1]} ); my $text = $self->_template_text('sad2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('sad3'); _html("$text"); } } sub _mostop { my $self = shift; my @ops = sort { $self->{stats}->{gaveops}{$b} <=> $self->{stats}->{gaveops}{$a} } keys %{ $self->{stats}->{gaveops} }; @ops = $self->_istoponly(@ops); my @deops = sort { $self->{stats}->{tookops}{$b} <=> $self->{stats}->{tookops}{$a} } keys %{ $self->{stats}->{tookops} }; @deops = $self->_istoponly(@deops); if (@ops) { my %hash = ( nick => $ops[0], ops => $self->{stats}->{gaveops}{$ops[0]} ); my $text = $self->_template_text('mostop1', %hash); _html("$text"); if (@ops >= 2) { my %hash = ( nick => $ops[1], ops => $self->{stats}->{gaveops}{$ops[1]} ); my $text = $self->_template_text('mostop2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mostop3'); _html("$text"); } if (@deops) { my %hash = ( nick => $deops[0], deops => $self->{stats}->{tookops}{$deops[0]} ); my $text = $self->_template_text('mostdeop1', %hash); _html("$text"); if (@deops >= 2) { my %hash = ( nick => $deops[1], deops => $self->{stats}->{tookops}{$deops[1]} ); my $text = $self->_template_text('mostdeop2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mostdeop3'); _html("$text"); } } sub _mostvoice { my $self = shift; my @voice = sort { $self->{stats}->{gavevoice}{$b} <=> $self->{stats}->{gavevoice}{$a} } keys %{ $self->{stats}->{gavevoice} }; @voice = $self->_istoponly(@voice); my @devoice = sort { $self->{stats}->{tookvoice}{$b} <=> $self->{stats}->{tookvoice}{$a} } keys %{ $self->{stats}->{tookvoice} }; @devoice = $self->_istoponly(@devoice); if (@voice) { my %hash = ( nick => $voice[0], voices => $self->{stats}->{gavevoice}{$voice[0]} ); my $text = $self->_template_text('mostvoice1', %hash); _html("$text"); if (@voice >= 2) { my %hash = ( nick => $voice[1], voices => $self->{stats}->{gavevoice}{$voice[1]} ); my $text = $self->_template_text('mostvoice2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mostvoice3'); _html("$text"); } if (@devoice) { my %hash = ( nick => $devoice[0], devoices => $self->{stats}->{tookvoice}{$devoice[0]} ); my $text = $self->_template_text('mostdevoice1', %hash); _html("$text"); if (@devoice >= 2) { my %hash = ( nick => $devoice[1], devoices => $self->{stats}->{tookvoice}{$devoice[1]} ); my $text = $self->_template_text('mostdevoice2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mostdevoice3'); _html("$text"); } } sub _mosthalfop { my $self = shift; my @halfops = sort { $self->{stats}->{gavehalfops}{$b} <=> $self->{stats}->{gavehalfops}{$a} } keys %{ $self->{stats}->{gavehalfops} }; @halfops = $self->_istoponly(@halfops); my @dehalfops = sort { $self->{stats}->{tookhalfops}{$b} <=> $self->{stats}->{tookhalfops}{$a} } keys %{ $self->{stats}->{tookhalfops} }; @dehalfops = $self->_istoponly(@dehalfops); if (@halfops) { my %hash = ( nick => $halfops[0], halfops => $self->{stats}->{gavehalfops}{$halfops[0]} ); my $text = $self->_template_text('mosthalfop1', %hash); _html("$text"); if (@halfops >= 2) { my %hash = ( nick => $halfops[1], halfops => $self->{stats}->{gavehalfops}{$halfops[1]} ); my $text = $self->_template_text('mosthalfop2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mosthalfop3'); _html("$text"); } if (@dehalfops) { my %hash = ( nick => $dehalfops[0], dehalfops => $self->{stats}->{tookhalfops}{$dehalfops[0]} ); my $text = $self->_template_text('mostdehalfop1', %hash); _html("$text"); if (@dehalfops >= 2) { my %hash = ( nick => $dehalfops[1], dehalfops => $self->{stats}->{tookhalfops}{$dehalfops[1]} ); my $text = $self->_template_text('mostdehalfop2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('mostdehalfop3'); _html("$text"); } } sub _mostactions { # The person who did the most /me's my $self = shift; my @actions = sort { $self->{stats}->{actions}{$b} <=> $self->{stats}->{actions}{$a} } keys %{ $self->{stats}->{actions} }; @actions = $self->_istoponly(@actions); if (@actions) { my %linehash = my %hash = ( nick => $actions[0], actions => $self->{stats}->{actions}{$actions[0]}, line => $self->_format_line($self->{stats}->{actionlines}{$actions[0]}) ); my $text = $self->_template_text('action1', %hash); if($self->{cfg}->{showactionline}) { my $exttext = $self->_template_text('actiontext', %hash); _html("$text
$exttext"); } else { _html("$text"); } if (@actions >= 2) { my %hash = ( nick => $actions[1], actions => $self->{stats}->{actions}{$actions[1]} ); my $text = $self->_template_text('action2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('action3'); _html("$text"); } } sub _mostsmiles { # The person(s) who smiled the most :-) my $self = shift; my %spercent; foreach my $nick (sort keys %{ $self->{stats}->{smiles} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { if ($self->{stats}->{lines}{$nick} > $self->{cfg}->{bignumbersthreshold}) { $spercent{$nick} = sprintf("%.1f", $self->{stats}->{smiles}{$nick} / $self->{stats}->{lines}{$nick} * 100); } } } my @smiles = sort { $spercent{$b} <=> $spercent{$a} } keys %spercent; if (@smiles) { my %hash = ( nick => $smiles[0], per => $spercent{$smiles[0]} ); my $text = $self->_template_text('smiles1', %hash); _html("$text"); if (@smiles >= 2) { my %hash = ( nick => $smiles[1], per => $spercent{$smiles[1]} ); my $text = $self->_template_text('smiles2', %hash); _html("
$text"); } _html(""); } else { my $text = $self->_template_text('smiles3'); _html("$text"); } } sub _lasttopics { my $self = shift; if ($self->{stats}->{topics}) { my %topic_seen; my %hash = ( total => scalar @{ $self->{stats}->{topics} } ); my $ltopic = $#{ $self->{stats}->{topics} }; my $tlimit = 0; $self->{cfg}->{topichistory} -= 1; if ($ltopic > $self->{cfg}->{topichistory}) { $tlimit = $ltopic - $self->{cfg}->{topichistory}; } for (my $i = $ltopic; $i >= $tlimit; $i--) { my $topic = $self->{stats}->{topics}[$i]{topic}; # This code makes sure that we don't see the same topic twice next if ($topic_seen{$topic}); $topic_seen{$topic} = 1; # Strip off the quotes (') $topic =~ s/^\'(.*)\'$/$1/; my $nick = $self->{stats}->{topics}[$i]{nick}; my $hour = $self->{stats}->{topics}[$i]{hour}; my $min = $self->{stats}->{topics}[$i]{min}; $hash{nick} = $nick; $hash{time} = "$hour:$min"; $hash{days} = $self->{stats}->{days} - $self->{stats}->{topics}[$i]{days}; if ($hash{days} == 0) { $hash{date} = $self->_template_text('today'); } elsif ($hash{days} == 1) { $hash{date} = $self->_template_text('lastseen1', %hash); } else { $hash{date} = $self->_template_text('lastseen2', %hash); } _html('' . $self->_format_line($topic) . ''); _html('' . $self->_template_text('bylinetopic', %hash) . ''); } _html("" . $self->_template_text('totaltopic', %hash) . ""); } else { _html("" . $self->_template_text('notopic') .""); } } sub _template_text { # This function is for the homemade template system. It receives a name # of a template and a hash with the fields in the template to update to # its corresponding value my $self = shift; my $template = shift; my %hash = @_; my $text; unless ($text = $self->{tmps}->{$self->{cfg}->{lang}}{$template}) { # Fall back to English if the language template doesn't exist if ($text = $self->{tmps}->{EN}{$template}) { print "Note: No translation in '$self->{cfg}->{lang}' for '$template' - falling back to English.\n" unless ($self->{cfg}->{silent}); } else { die("No template for '$template' in language file.\n"); } } if($self->{iconv}) { $text = $self->{iconv}->convert($text); die("Could not convert charset for template '$template'.\n") unless $text; } $hash{channel} = $self->{cfg}->{channel}; # the nick is sanitized here, everything else outside of _template_text $hash{nick} = $self->_format_word($hash{nick}) if $hash{nick}; foreach my $key (sort keys %hash) { $text =~ s/\[:$key\]/$hash{$key}/; } if ($text =~ /\[:[^:]*?:[^:]*?:[^:]*?:\]/o) { $text =~ s/\[:([^:]*?):([^:]*?):([^:]*?):\]/$self->_get_subst($1,$2,$3,\%hash)/geo; } if ($text =~ /\[:[^:]*?:[^:]*?:]/o) { $text =~ s/\[:([^:]*?):([^:]*?):]/$self->_get_subst($1,$2,undef,\%hash)/geo; } return $text; } sub _format_word { # This function formats a word -- should ONLY be called on words used alone (EG: not whole line printed) my ($self, $word, $nick) = @_; # nick is only defined for user links in top table $word = htmlentities($word, $self->{cfg}->{charset}); $word = $self->_replace_links($word, $nick); return $word; } sub _format_line { # This function formats a action/normal line to be more readable, and calls any other function # that should be executed on every line. my ($self, $line) = @_; my $hashref; if ($hashref = $self->{cfg}->{analyzer}->{parser}->normalline($line)) { $line = '<' . $hashref->{nick} . '> ' . $hashref->{saying}; } elsif ($hashref = $self->{cfg}->{analyzer}->{parser}->actionline($line)) { $line = '* ' . $hashref->{nick} . ' ' . $hashref->{saying}; } elsif ($hashref = $self->{cfg}->{analyzer}->{parser}->thirdline($line)) { if (defined($hashref->{kicker})) { $line = '*** ' . $hashref->{nick} . ' was kicked by ' . $hashref->{kicker}; $line .= ' (' . $hashref->{kicktext} . ')' if (defined($hashref->{kicktext})); } elsif (defined($hashref->{newtopic})) { $line = '*** ' . $hashref->{nick} . ' changes topic to \'' . $hashref->{newtopic} . '\''; } elsif (defined($hashref->{newmode})) { $line = '*** ' . $hashref->{nick} . ' sets mode ' . $hashref->{newmode}; $line .= ' ' . $hashref->{modechanges} if (defined($hashref->{kicktext})); } elsif (defined($hashref->{newjoin})) { $line = '*** Joins: ' . $hashref->{nick}; } elsif (defined($hashref->{newnick})) { $line = '*** ' . $hashref->{nick} . ' is now known as ' . $hashref->{newnick}; } elsif (defined($hashref->{newtopic})) { $line = '*** ' . $hashref->{nick} . ' changes topic to: ' . $hashref->{newtopic}; } } $line = htmlentities($line, $self->{cfg}->{charset}); $line = $self->_replace_links($line); return $line; } sub _get_subst { # This function looks at the user definition and see if there is sex # defined. If yes, return the appropriate value. If no, just return the # default he/she value. my $self = shift; my ($m,$f,$d,$hash) = @_; if ($hash->{nick} && $self->{users}->{sex}{$hash->{nick}}) { if ($self->{users}->{sex}{$hash->{nick}} eq 'm') { return $m; } elsif ($self->{users}->{sex}{$hash->{nick}} eq 'f') { return $f; } } return defined($d) ? $d : "$m/$f"; } sub _mostusedword { # Word usage statistics my $self = shift; my %usages; foreach my $word (keys %{ $self->{stats}->{wordcounts} }) { # Skip people's nicks. next if is_nick($word, $self->{cfg}->{cachedir}); next if (length($word) < $self->{cfg}->{wordlength}); $usages{$word} = $self->{stats}->{wordcounts}{$word}; } my @popular = sort { $usages{$b} <=> $usages{$a} } keys %usages; if (@popular) { $self->_headline($self->_template_text('mostwordstopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); my $count = 0; for(my $i = 0; $count < $self->{cfg}->{wordhistory}; $i++) { last unless $i < $#popular; # Skip nicks. It's far more efficient to do this here than when # @popular is created. next if is_ignored($popular[$i]); my $a = $count + 1; my $popular = $self->_format_word($self->{stats}->{word_upcase}{$popular[$i]}); my $wordcount = $self->{stats}->{wordcounts}{$popular[$i]}; my $lastused = $self->_format_word($self->{stats}->{wordnicks}{$popular[$i]}); my $class; if ($a == 1) { $class = 'hirankc'; } else { $class = 'rankc'; } _html(""); _html(""); _html(""); _html(""); _html(""); $count++; } _html("
 " . $self->_template_text('word') . "" . $self->_template_text('numberuses') . "" . $self->_template_text('lastused') . "
$a$popular$wordcount$lastused
"); } } sub _mostwordsperline { # The person who got the most words per line my $self = shift; my %wpl = (); my $numlines = 0; my ($avg, $numwords); foreach my $nick (keys %{ $self->{stats}->{words} }) { if ($self->{topactive}{$nick} || !$self->{cfg}->{showonlytop}) { $wpl{$nick} = sprintf("%.2f", $self->{stats}->{words}{$nick}/$self->{stats}->{lines}{$nick}); $numlines += $self->{stats}->{lines}{$nick}; $numwords += $self->{stats}->{words}{$nick}; } } if ($numlines > 0) { $avg = sprintf("%.2f", $numwords/$numlines); } my @wpl = sort { $wpl{$b} <=> $wpl{$a} } keys %wpl; if (@wpl) { my %hash = ( nick => $wpl[0], wpl => $wpl{$wpl[0]} ); my $text = $self->_template_text('wpl1', %hash); _html("$text"); $hash{avg} = $avg; $text = $self->_template_text('wpl2', %hash); _html("
$text"); _html(""); } } sub _mostreferencednicks { # List showing the most referenced nicks my $self = shift; my %usages; foreach my $word (sort keys %{ $self->{stats}->{wordcounts} }) { next if is_ignored($word); my $nick = is_nick($word) or next; next if !exists $self->{stats}->{lines}{$nick}; $usages{$word} = $self->{stats}->{wordcounts}{$word}; } my @popular = sort { $usages{$b} <=> $usages{$a} } keys %usages; if (@popular) { $self->_headline($self->_template_text('referencetopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); for(my $i = 0; $i < $self->{cfg}->{nickhistory}; $i++) { last if $i >= @popular; my $a = $i + 1; my $popular = $self->_format_word(is_nick($popular[$i])); my $wordcount = $self->{stats}->{wordcounts}{$popular[$i]}; my $lastused = $self->_format_word($self->{stats}->{wordnicks}{$popular[$i]} || ""); # this is undefined when a nick is referenced before being used # first (this is a minor bug we ignore here, see test/01.cfg) my $class; if ($a == 1) { $class = 'hirankc'; } else { $class = 'rankc'; } _html(""); _html(""); _html(""); _html(""); _html(""); } _html("
 " . $self->_template_text('nick') . "" . $self->_template_text('numberuses') . "" . $self->_template_text('lastused') . "
$a$popular$wordcount$lastused
"); } } sub _smileys { my $self = shift; my %usages; foreach my $smiley (sort keys %{ $self->{stats}->{smileys} }) { $usages{$smiley} = $self->{stats}->{smileys}{$smiley}; } my @popular = sort { $usages{$b} <=> $usages{$a} } keys %usages; return unless @popular; $self->_headline($self->_template_text('smileytopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); for(my $i = 0; $i < $self->{cfg}->{smileyhistory}; $i++) { last if $i >= @popular; my $a = $i + 1; my $popular = $self->_format_word($popular[$i]); my $count = $self->{stats}->{smileys}{$popular[$i]}; my $lastused = $self->_format_word($self->{stats}->{smileynicks}{$popular[$i]} || ""); my $class = ($a == 1) ? 'hirankc' : 'rankc'; _html(""); _html(""); _html(""); _html(""); _html(""); } _html("
 " . $self->_template_text('smiley') . "" . $self->_template_text('numberuses') . "" . $self->_template_text('lastused') . "
$a$popular$count$lastused
"); } sub _karma { # List showing the most referenced nicks my $self = shift; my %karma; foreach my $thing (sort keys %{ $self->{stats}->{karma} }) { my $Thing = lc(is_nick($thing) || $thing); # FIXME: this is ugly foreach my $nick (keys %{ $self->{stats}->{karma}{$thing} }) { $karma{$Thing} += $self->{stats}->{karma}{$thing}{$nick}; } } my @popular = sort { $karma{$b} <=> $karma{$a} } keys %karma; return unless @popular; $self->_headline($self->_template_text('karmatopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); _html(""); my @goodpos = grep { $karma{$_} > 0 } @popular; splice @goodpos, $self->{cfg}->{karmahistory}, @goodpos if @goodpos > $self->{cfg}->{karmahistory}; my @badpos = grep { $karma{$_} < 0 } @popular; splice @badpos, 0, @badpos - $self->{cfg}->{karmahistory} if @badpos > $self->{cfg}->{karmahistory}; my $pos = 0; foreach my $thing (@goodpos) { my $class = ($pos++ == 0) ? 'hirankc' : 'rankc'; my $Thing = $self->_format_word(is_nick($thing) || $thing); # ugliness #2 _html(""); _html(""); _html(""); my @k = grep { $self->{stats}->{karma}{$thing}{$_} > 0 } (keys %{ $self->{stats}->{karma}{$thing} }); @k = $self->_trimlist(@k); my $n = join ', ', map { $self->_format_word($_) } @k; _html(""); @k = grep { $self->{stats}->{karma}{$thing}{$_} < 0 } (keys %{ $self->{stats}->{karma}{$thing} }); @k = $self->_trimlist(@k); $n = join ', ', map { $self->_format_word($_) } @k; _html(""); _html(""); } if (@goodpos and @badpos) { _html(""); _html(""); _html(""); } $pos = @badpos; foreach my $thing (@badpos) { my $class = ($pos == 1) ? 'hirankc' : 'rankc'; my $Thing = $self->_format_word(is_nick($thing) || $thing); _html(""); _html(""); _html(""); my @k = grep { $self->{stats}->{karma}{$thing}{$_} > 0 } (keys %{ $self->{stats}->{karma}{$thing} }); @k = $self->_trimlist(@k); my $n = join ', ', map { $self->_format_word($_) } @k; _html(""); @k = grep { $self->{stats}->{karma}{$thing}{$_} < 0 } (keys %{ $self->{stats}->{karma}{$thing} }); @k = $self->_trimlist(@k); $n = join ', ', map { $self->_format_word($_) } @k; _html(""); _html(""); } _html("
 " . $self->_template_text('nick') . "" . $self->_template_text('karma') . "" . $self->_template_text('goodkarma') . "" . $self->_template_text('badkarma') . "
$pos$Thing$karma{$thing}$n$n
". ($pos--) ."$Thing$karma{$thing}$n$n
"); } sub _mosturls { # List showing the most referenced URLs my $self = shift; my @sorturls = sort { $self->{stats}->{urlcounts}{$b} <=> $self->{stats}->{urlcounts}{$a} } keys %{ $self->{stats}->{urlcounts} }; if (@sorturls) { $self->_headline($self->_template_text('urlstopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); for(my $i = 0; $i < $self->{cfg}->{urlhistory}; $i++) { last unless $i < @sorturls; my $a = $i + 1; my $urlcount = $self->{stats}->{urlcounts}{$sorturls[$i]}; my $lastused = $self->{stats}->{urlnicks}{$sorturls[$i]}; my $printurl = $sorturls[$i]; if ($printurl and length($printurl) > 60) { $printurl = substr($printurl, 0, 60); } $printurl = htmlentities($printurl, $self->{cfg}->{charset}); my $linkurl = urlencode($sorturls[$i]); my $class = ($a == 1) ? 'hirankc' : 'rankc'; _html(""); _html(""); _html(""); _html(""); _html(""); } _html("
 " . $self->_template_text('url') . "" . $self->_template_text('numberuses') . "" . $self->_template_text('lastused') . "
$a$printurl$urlcount$lastused
"); } } sub _charts { # List showing the most played songs my $self = shift; my @sortcharts = sort { $self->{stats}->{chartcounts}{$b} <=> $self->{stats}->{chartcounts}{$a} } keys %{ $self->{stats}->{chartcounts} }; if (@sortcharts) { $self->_headline($self->_template_text('chartstopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); for(my $i = 0; $i < $self->{cfg}->{chartshistory}; $i++) { last unless $i < @sortcharts; my $a = $i + 1; my $song = $sortcharts[$i]; my $chartcount = $self->{stats}->{chartcounts}{$song}; my $lastused = $self->{stats}->{chartnicks}{$song}; $song = $self->{stats}->{word_upcase}{$song}; $song = substr($song, 0, 60) if (length($song) > 60); $song = $self->_format_word($song); my $class = ($a == 1) ? 'hirankc' : 'rankc'; _html(""); _html(""); _html(""); _html(""); _html(""); } _html("
 " . $self->_template_text('song') . "" . $self->_template_text('numberplayed') . "" . $self->_template_text('playedby') . "
$a$song$chartcount$lastused
"); } } sub _legend { # A legend showing the timebars and their associated time. my $self = shift; _html(""); _html(""); _html(""); _html(""); _html(""); _html("
{cfg}->{piclocation}/$self->{cfg}->{pic_h_0}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"0-5\" /> = 0-5{cfg}->{piclocation}/$self->{cfg}->{pic_h_6}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"6-11\" /> = 6-11{cfg}->{piclocation}/$self->{cfg}->{pic_h_12}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"12-17\" /> = 12-17{cfg}->{piclocation}/$self->{cfg}->{pic_h_18}\" width=\"40\" height=\"15\" align=\"middle\" alt=\"18-23\" /> = 18-23
"); } sub _replace_url # used internally by _replace_links { my ($self, $url, $www, $ftp, $text) = @_; $url = "http://$url" if $www; $url = "ftp://$url" if $ftp; my $texturl = $self->_template_text("newwindow"); return "" . $self->_split_long_text($text) . ''; } sub _replace_email # used internally by _replace_links { my ($self, $mailto, $user, $domain, $nick) = @_; $mailto = '' if $nick or not $mailto; $nick ||= "$user@$domain"; # obfuscate mail address my $textmail = $self->_template_text("mailto"); return "" . $self->_split_long_text($mailto . $nick) . "<\/a>"; } sub _replace_links { # replace URLs and email addresses by links my ($self, $str, $nick) = @_; # nick is only defined for user links in top table # Regular expressions are taken from match_urls() and match_email() in # Common.pm my (@str) = split(/ /,$str); foreach (@str) { s/((?:(?:https?|ftp|telnet|news):\/\/|(?:(?:(www)|(ftp))[\w-]*\.))[-\w\/~\@:]+\.\S+[\w\/])/$self->_replace_url($1, $2, $3, $nick || $1)/egio or s/(mailto:)?([-\w.]+)@([-\w]+\.[-\w.]+)/$self->_replace_email($1, $2, $3, $nick)/egio or $_ = $self->_split_long_text($_); } return join(' ', @str); } sub _split_long_text { my ($self, $str) = @_; $str =~ s/(\S{$self->{cfg}->{quotewidth}})(?!\s)/$1-
/og; return($str); } sub _user_linetimes { my $self = shift; my $nick = shift; my $top = shift; my $bar = ""; my $len = ($self->{stats}->{lines}{$nick} / $self->{stats}->{lines}{$top}) * 100; for (my $i = 0; $i <= 3; $i++) { my $l = $self->{stats}->{line_times}{$nick}[$i]; next if not defined $l; my $w = int(($l / $self->{stats}->{lines}{$nick}) * $len); if ($w) { my $pic = 'pic_h_'.(6*$i); $bar .= "{cfg}->{piclocation}/$self->{cfg}->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" align=\"middle\" alt=\"$l\" title=\"$l\" />"; } } return "$bar $self->{stats}->{lines}{$nick}"; } sub _user_wordtimes { my $self = shift; my $nick = shift; my $top = shift; $self->{stats}->{words}{$nick} ||= 0; my $len = ($self->{stats}->{words}{$nick} / $self->{stats}->{words}{$top}) * 100; my $bar = ""; for (my $i = 0; $i <= 3; $i++) { next if not defined $self->{stats}->{word_times}{$nick}[$i]; my $w = int(($self->{stats}->{word_times}{$nick}[$i] / $self->{stats}->{words}{$nick}) * $len); if ($w) { my $pic = 'pic_h_'.(6*$i); $bar .= "{cfg}->{piclocation}/$self->{cfg}->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" align=\"middle\" alt=\"\" />"; } } return "$bar $self->{stats}->{words}{$nick}"; } sub _user_times { my $self = shift; my ($nick) = @_; my $bar = ""; my $itemstat = ($self->{cfg}->{sortbywords} ? 'words' : 'lines'); my $timestat = ($self->{cfg}->{sortbywords} ? 'word_times' : 'line_times'); for (my $i = 0; $i <= 3; $i++) { my $l = $self->{stats}->{$timestat}{$nick}[$i]; next if not defined $l; my $w = int(($l / $self->{stats}->{$itemstat}{$nick}) * 40); if ($w) { my $pic = 'pic_h_'.(6*$i); $bar .= "{cfg}->{piclocation}/$self->{cfg}->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" alt=\"$l\" title=\"$l\" />"; } } return $bar; } sub _user_pic { my $self = shift; my $nick = shift; my $style = shift; return unless $self->{users}->{userpics}{$nick} or $self->{cfg}->{defaultpic}; my $rowspan = $self->{cfg}->{userpics} ? " rowspan=\"$self->{cfg}->{userpics}\"" : ""; my $output = ""; my $biguserpic = $self->{users}->{biguserpics}{$nick}; if ($biguserpic) { $biguserpic = $self->{cfg}->{imagepath} . randomglob($biguserpic, $self->{cfg}->{imageglobpath}, $nick) if $biguserpic !~ /^http:\/\//i; $output .= "
"; } my $pic = $self->{users}->{userpics}{$nick} || $self->{cfg}->{defaultpic}; $pic = $self->{cfg}->{imagepath} . randomglob($pic, $self->{cfg}->{imageglobpath}, $nick) unless $pic =~ /^http:\/\//i; my $height = $self->{cfg}->{picheight} ? " height=\"$self->{cfg}->{picheight}\"" : ""; my $width = $self->{cfg}->{picwidth} ? " width=\"$self->{cfg}->{picwidth}\"" : ""; my $alt = $self->{users}->{userpics}{$nick} ? " alt=\"$nick\" title=\"$nick\"" : ""; my $border = $biguserpic ? ' border="0"' : ''; $output .= ""; $output .= "" if $biguserpic; _html("$output"); } sub _mostnicks { # List showing the user with most used nicks my $self = shift; my @sortnicks = sort { keys %{ $self->{stats}->{nicks}->{$b} } <=> keys %{ $self->{stats}->{nicks}->{$a} } } keys %{ $self->{stats}->{nicks} }; if (keys %{ $self->{stats}->{nicks}->{$sortnicks[0]} } > 1) { $self->_headline($self->_template_text('mostnickstopic')); my $names1 = $self->_template_text('names1'); my $names2 = $self->_template_text('names2'); my $nick_txt = $self->_template_text('nick'); my $names_txt = $self->_template_text('names'); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); my $a = 0; foreach my $nick (@sortnicks) { next if is_ignored($nick); my $nickcount = keys %{ $self->{stats}->{nicks}->{$nick} }; my @nicks = values %{ $self->{stats}->{nicks}->{$nick} }; my $nickused = join(", ", $self->_trimlist(@nicks)); last unless ($nickcount > 1); $a++; my $class = $a == 1 ? 'hirankc' : 'rankc'; my $n = $nickcount > 1 ? $names1 : $names2; _html(""); if ($self->{cfg}->{mostnicksverbose}) { _html(""); _html(""); } else { _html(""); _html(""); } _html(""); last if $a >= $self->{cfg}->{mostnickshistory}; } _html("
 $nick_txt$names_txt
$a$nick ($nickcount $n)$nickused$nick$nickcount $n
"); } } sub _mostactivebyhour { # Charts for most active nicks by hour (0-5, 6-11, 12-17, 18-23) my $self = shift; my $sortnicks; my $lastline=-1; my $maxlines=0; foreach my $period (0,1,2,3) { my @sortnicks = sort { (defined $self->{stats}->{line_times}{$b}[$period]?$self->{stats}->{line_times}{$b}[$period]:0) <=> (defined $self->{stats}->{line_times}{$a}[$period]?$self->{stats}->{line_times}{$a}[$period]:0) } keys %{ $self->{stats}->{line_times} } ; for(my $i = 0; $i < $self->{cfg}->{activenicksbyhour}; $i++) { next if ! $sortnicks[$i]; next if is_ignored($sortnicks[$i]); last unless $i < @sortnicks; my $nick=$sortnicks[$i]; my $count=$self->{stats}->{line_times}{$nick}[$period] || 0; last unless $nick; last unless $count; $sortnicks->[$period][$i]=$nick; if ($lastline<$i) { $lastline=$i; } if ($maxlines<$count) { $maxlines=$count; } } } if ($lastline>=0) { $self->_headline($self->_template_text('activenickbyhourtopic')); _html("{cfg}->{tablewidth}\">"); _html(""); _html(""); _html(""); _html(""); _html(""); _html(""); for(my $i = 0; $i <= $lastline; $i++) { my $a = $i + 1; my $class = $a == 1 ? 'hirankc' : 'rankc'; _html(""); foreach my $period (0,1,2,3) { my $nick=$sortnicks->[$period][$i]; if ($nick) { my $count=$self->{stats}->{line_times}{$nick}[$period]; if ($count) { _html(""); } else { _html(""); } } else { _html(""); } } _html(""); } _html("
 0-56-1112-1718-23
$a"); if ($self->{cfg}->{showmostactivebyhourgraph}) { my $pic = 'pic_h_'.(6*$period); my $w = int(($count / $maxlines) * 100) || 1; _html("{cfg}->{piclocation}/$self->{cfg}->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" align=\"middle\" alt=\"\" />"); } _html($self->_format_word($nick)." - ".$count); _html("  
"); } } sub _topactive { my $self = shift; my @top_active; my $top_nicks; if ($self->{cfg}->{sortbywords}) { @top_active = sort { $self->{stats}->{words}{$b} <=> $self->{stats}->{words}{$a} } keys %{ $self->{stats}->{words} }; $top_nicks = scalar keys %{ $self->{stats}->{words} }; } else { @top_active = sort { $self->{stats}->{lines}{$b} <=> $self->{stats}->{lines}{$a} } keys %{ $self->{stats}->{lines} }; $top_nicks = scalar keys %{ $self->{stats}->{lines} }; } if ($self->{cfg}->{activenicks} > $top_nicks) { $self->{cfg}->{activenicks} = $top_nicks; } if (($self->{cfg}->{activenicks}+$self->{cfg}->{activenicks2}) > $top_nicks) { $self->{cfg}->{activenicks2} = $top_nicks-$self->{cfg}->{activenicks}; } (@top_active) = @top_active[0..($self->{cfg}->{activenicks}-1)]; $self->{stats}->{topactive_lines} = @top_active ? $self->{stats}->{lines}{$top_active[0]} : 1; foreach (@top_active) { $self->{topactive}{$_} = 1; } } sub _istoponly { my $self = shift; my (@nicks_tmp) = @_; my @nicks; my $cnt=0; if ($self->{cfg}->{showonlytop}) { foreach my $nick (@nicks_tmp) { if ($self->{topactive}{$nick}) { push(@nicks, $nick); } } return(@nicks); } else { return(@nicks_tmp); } } sub _trimlist { my $self = shift; return @_ unless $self->{cfg}->{nicklimit}; splice @_, $self->{cfg}->{nicklimit}, @_, qw/.../ if @_ > $self->{cfg}->{nicklimit}; return @_; } sub _activegenders { # The most active gender in the channel my $self = shift; my @topgender = sort {$self->{stats}->{sex_lines}{$b} <=> $self->{stats}->{sex_lines}{$a}} keys %{$self->{stats}->{sex_lines}}; return unless @topgender; $self->_headline($self->_template_text('activegenderstopic')); _html("{cfg}->{tablewidth}\">"); _html(" " . "" . "" . "" ); my $i = 1; for my $gender (@topgender) { my $bar = ""; my $len = ($self->{stats}->{sex_lines}{$gender} / $self->{stats}->{sex_lines}{$topgender[0]}) * 100; for (0 .. 3) { next if not defined $self->{stats}->{sex_line_times}{$gender}[$_]; my $w = int(($self->{stats}->{sex_line_times}{$gender}[$_] / $self->{stats}->{sex_lines}{$gender}) * $len); if ($w) { my $pic = 'pic_h_'.(6*$_); $bar .= "{cfg}->{piclocation}/$self->{cfg}->{$pic}\" border=\"0\" width=\"$w\" height=\"15\" align=\"middle\" alt=\"$self->{stats}->{sex_line_times}{$gender}[$_]\" />"; } } my @top_active = sort { $self->{stats}->{lines}{$b} <=> $self->{stats}->{lines}{$a} } grep { $self->{users}->{sex}{$_} and $self->{users}->{sex}{$_} eq $gender } keys %{ $self->{stats}->{lines} }; my $nicklist = join ", ", map { $_ . ($self->{stats}->{lines}{$_} ? " ($self->{stats}->{lines}{$_})" : "") } $self->_trimlist(@top_active); my $class = ($i == 1 ? "hirankc" : "rankc"); my $span_class = $gender eq 'm' ? "male" : ($gender eq 'f' ? "female" : "bot"); _html(""); _html(" "); _html(" "); _html(" "); _html(" "); $i++; } _html("
 " . $self->_template_text('gender') . "" . $self->_template_text('numberlines') . "" . $self->_template_text('nick') . "
$i" . $self->_template_text("gender_$gender") . "$bar $self->{stats}->{sex_lines}{$gender}$nicklist
"); } 1; __END__ =head1 NAME Pisg::HTMLGenerator - class to create a static HTML page out of data parsed =head1 DESCRIPTION C uses the hash returned by Pisg::Parser::Logfile and turns it into a static HTML page. =head1 SYNOPSIS use Pisg::HTMLGenerator; $generator = new Pisg::HTMLGenerator( cfg => $cfg, stats => $stats, users => $users, tmps => $tmps ); =head1 CONSTRUCTOR =over 4 =item new ( [ OPTIONS ] ) This is the constructor for a new Pisg::HTMLGenerator object. C are passed in a hash like fashion using key and value pairs. Possible options are: B - hashref containing configuration variables, created by the Pisg module. B - reference to the hash returned by Pisg::Parser::Logfile containing all stats. B - reference to a hash containg user information B - reference to a hash containing the language templates. =back =head1 AUTHOR Morten Brix Pedersen =head1 COPYRIGHT Copyright (C) 2001-2005 Morten Brix Pedersen. All rights reserved. Copyright (C) 2003-2005 Christoph Berg . This program is free software; you can redistribute it and/or modify it under the terms of the GPL, license is included with the distribution of this file. =cut pisg-0.73/modules/Pisg/Common.pm0000774000076400007650000001470311705647720015222 0ustar wadewadepackage Pisg::Common; # pisg - Perl IRC Statistics Generator # # Copyright (C) 2001-2005 - morten@wtf.dk # Copyright (C) 2003-2005 Christoph Berg # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA =head1 NAME Pisg::Common - some common functions of pisg. =cut use Exporter; @ISA = ('Exporter'); @EXPORT = qw(add_alias add_aliaswild add_ignore add_url_ignore is_ignored url_is_ignored find_alias store_aliases restore_aliases match_urls match_email htmlentities urlencode is_nick randomglob wordlist_regexp); use strict; $^W = 1; my (%aliases, %aliaswilds, %ignored, %aliasseen, %ignored_urls, %url_seen); my (%aliases2, %aliaswilds2, %ignored2, %aliasseen2, %ignored_urls2, %url_seen2); # add_alias assumes that the first argument is the true nick and the second is # the alias, but will accomidate other arrangements if necessary. sub add_alias { my ($nick, $alias) = @_; my $lcnick = lc($nick); my $lcalias = lc($alias); if (not defined $aliases{$lcnick}) { if (not defined $aliases{$lcalias}) { $aliases{$lcnick} = $nick; $aliases{$lcalias} = $nick; } else { $aliases{$lcnick} = $aliases{$lcalias}; } } elsif (not defined $aliases{$lcalias}) { $aliases{$lcalias} = $aliases{$lcnick}; } } sub add_aliaswild { my ($nick, $alias) = @_; my $lcnick = lc($nick); my $lcalias = lc($alias); if (not defined $aliases{$lcnick}) { $aliases{$lcnick} = $nick; } $aliaswilds{$lcalias} = $nick; } sub add_ignore { my $nick = shift; $ignored{$nick} = 1; } sub is_ignored { my $nick = shift; if ($ignored{$nick}) { return 1; } elsif ($ignored{is_nick($nick)}) { $ignored{$nick} = 1; } else { $ignored{$nick} = 0; } } sub url_is_ignored { my $url = shift; if ($ignored_urls{$url}) { return 1; } } sub add_url_ignore { my $url = shift; $ignored_urls{$url} = 1; } # Sub to do a -cheap- check on wether or not a word is a nick # This will only match if it has seen it used as a nick sub is_nick { my ($nick, $wilds) = @_; my $lcnick = lc($nick); if ($aliases{$lcnick}) { return $aliases{$lcnick}; } elsif ($aliasseen{$lcnick}) { return $aliasseen{$lcnick} } # check aliaswilds if were are in _mostusedword() if (defined $wilds) { foreach (keys %aliaswilds) { if ($lcnick =~ /^$_$/i) { add_alias($aliaswilds{$_}, $lcnick); return $aliaswilds{$_}; } } } return 0; } # For efficiency reasons, find_alias() caches aliases when it finds them, # because the regexp search through %aliaswilds is *really* expensive. # %aliasseen is used to mark nicks for which nothing matches--we can't add # such nicks to an actual alias, though, because they might be aliased (e.g. # by a nick change) later. sub find_alias { my ($nick) = @_; my $lcnick = lc($nick); if ($aliases{$lcnick}) { return $aliases{$lcnick}; } elsif ($aliasseen{$lcnick}) { return $aliasseen{$lcnick}; } else { foreach (keys %aliaswilds) { if ($nick =~ /^$_$/i) { add_alias($aliaswilds{$_}, $lcnick); return $aliaswilds{$_}; } } } $aliasseen{$lcnick} = $nick; return $nick; } sub store_aliases { %aliases2 = %aliases; %aliaswilds2 = %aliaswilds; %ignored2 = %ignored; %aliasseen2 = %aliasseen; %ignored_urls2 = %ignored_urls; %url_seen2 = %url_seen; } sub restore_aliases { %aliases = %aliases2; %aliaswilds = %aliaswilds2; %ignored = %ignored2; %aliasseen = %aliasseen2; %ignored_urls = %ignored_urls2; %url_seen = %url_seen2; } sub match_urls { my $str = shift; my @urls; # we don't treat mailto: as URL here while ($str =~ /((?:(?:https?|ftp|telnet|news):\/\/|(?:(?:(www)|(ftp))[\w-]*\.))[-\w\/~\@:]+\.\S+[\w\/])/gio) { my $url = $2 ? "http://$1" : ($3 ? "ftp://$1" : $1); my $url_strip = $url; $url_strip =~ s/\/$//; $url_seen{$url_strip} ||= $url; # normalize URL to first seen form push (@urls, $url_seen{$url_strip}); } return @urls; } sub htmlentities { my $str = shift; my $charset = shift; return $str unless $str; $str =~ s/\&/\&/go; $str =~ s/\/\>/go; if ($charset and $charset =~ /iso-8859-1/i) { # this is for people without Text::Iconv $str =~ s/ü/ü/go; $str =~ s/ö/ö/go; $str =~ s/ä/ä/go; $str =~ s/ß/ß/go; $str =~ s/å/å/go; $str =~ s/æ/æ/go; $str =~ s/ø/ø/go; $str =~ s/Å/Å/go; $str =~ s/Æ/Æ/go; $str =~ s/Ø/Ø/go; $str =~ s/\x95/\•/go; } return $str; } sub urlencode { my $str = shift; $str =~ s/([^\w_.\/?=:+-])/sprintf "%%%02X", ord($1)/ge; return $str; } sub randomglob { my ($pattern, $globpath, $nick) = @_; return $pattern unless $pattern =~ /[*?]/; my @globs = glob $globpath . $pattern; my $return = $globs[int(rand(@globs))]; unless($return) { print STDERR "Warning: picture $globpath$pattern for $nick not found\n"; return $pattern; } $return =~ s/^$globpath//; return $return; } sub wordlist_regexp { my $list = shift; $list =~ s/^\s+//; # split ignores trailing empty fields my @words = split(/\s+/, $list); my $regexpaliases = shift; unless($regexpaliases) { map { $_ = quotemeta; # quote everything s/\\\*/\\S*/g; # replace \* s/^\\S\*// or $_ = "\\b$_"; # ... but remote it at beginning/end of word s/\\S\*$// or $_ = "$_\\b"; } @words; } return join '|', @words; } 1; pisg-0.73/modules/Pisg/Parser/0000775000076400007650000000000011705647720014661 5ustar wadewadepisg-0.73/modules/Pisg/Parser/Format/0000775000076400007650000000000011705647720016111 5ustar wadewadepisg-0.73/modules/Pisg/Parser/Format/lulubot.pm0000774000076400007650000000417711705647720020150 0ustar wadewade# This is the lulubot log parser by Vianney Lecroart # More info about lulubot here: http://lulubot.berlios.de and # here: http://developer.berlios.de/projects/lulubot # Version tested with the CVS the 12/04/04 # [22-11-2004/14:42] *** Joined ace (~ace@154.25.145.85) # [22-11-2004/15:00] morning # [22-11-2004/15:01] * ace is back package Pisg::Parser::Format::lulubot; use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[[^/]+/(\d+):\d+\] <([^>]+)> (.*)$', actionline => '^\[[^/]+/(\d+):\d+\] \* (\S+) (.*)$', thirdline => '^\[[^/]+/(\d+):(\d+)\] \*{3} (\S+) (\S+) (.*)$', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; # Format-specific stuff goes here. if ($3 eq 'Joined') { $hash{newjoin} = $4; $hash{nick} = $4; } elsif ($4 eq 'changed') { $5 =~ /^topic to (.*)$/; $hash{newtopic} = $1; } elsif ($4 eq 'is') { $5 =~ /^now known as (.*)$/; $hash{newnick} = $1; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/bxlog.pm0000774000076400007650000000402111705647720017561 0ustar wadewadepackage Pisg::Parser::Format::bxlog; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[\d+ \S+\/(\d+):\d+\] <([^>]+)> (.*)', actionline => '^\[\d+ \S+\/(\d+):\d+\] \* (\S+) (.*)', thirdline => '^\[\d+ \S+\/(\d+):(\d+)\] ([<>@!]) (.*)' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; if ($3 eq '<') { if ($4 =~ /^([^!]+)!\S+ was kicked off \S+ by ([^!]+)!/) { $hash{kicker} = $2; $hash{nick} = $1; } } elsif ($3 eq '>') { if ($4 =~ /^([^!]+)!\S+ has joined \S+$/) { $hash{nick} = $1; $hash{newjoin} = $1; } } elsif ($3 eq '@') { if ($4 =~ /^Topic by ([^!:])[!:]*: (.*)$/) { $hash{nick} = $1; $hash{newtopic} = $2; } elsif ($4 =~ /^mode \S+ \[([\S]+) [^\]]+\] by ([^!]+)!\S+$/) { $hash{newmode} = $1; $hash{nick} = $2; } } elsif ($3 eq '!') { if ($4 =~ /^(\S+) is known as (\S+)$/) { $hash{nick} = $1; $hash{newnick} = $2; } } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/kvirc.pm0000774000076400007650000000325011705647720017567 0ustar wadewadepackage Pisg::Parser::Format::kvirc; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+[^ ]+ <([^>]+)> (.*)', actionline => '^\[(\d+):\d+[^ ]+ \*\*\* (\S+) (.*)', thirdline => '^\[(\d+):(\d+)[^ ]+ (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5.$6) eq 'hasbeenkicked') { $hash{kicker} = $10; } elsif (($5.$6) eq 'setstopic') { $hash{newtopic} = ($10.' '.$11); } elsif (($5.$6) eq 'setsmode') { #can't be matched yet $hash{newmode} = substr($7, 1); } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $1; } elsif (($5.$6.$7) eq 'isnowknown') { $hash{newnick} = $9; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/rbot.pm0000774000076400007650000000422011705647720017415 0ustar wadewadepackage Pisg::Parser::Format::rbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '\[\d+/\d+/\d+ (\d+):\d+:\d+\] <([^>\s]+)>\s+(.*)', actionline => '\[\d+/\d+/\d+ (\d+):\d+:\d+\] \*{1,}\s+(\S+) (.*)', thirdline => '\[\d+/\d+/\d+ (\d+):(\d+):\d+\] @ ([^:\s]+):? ([^:\s]+):? (\S+) (\S+) ?(\S+)? ?(.*)?', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($3 and (($3) eq 'Quit')) { $hash{nick} = $4; } elsif (($3) eq 'Mode') { if (($4) eq '+o') { $hash{newmode} = '+o'; $hash{nick} = $5; } elsif (($4) eq '-o') { $hash{newmode} = '-o'; $hash{nick} = $5; } elsif (($4) eq '+v') { $hash{newmode} = '+v'; $hash{nick} = $5; } elsif (($4) eq '-v') { $hash{newmode} = '-v'; $hash{nick} = $5; } }elsif (($4.$5) eq 'joinedchannel') { $hash{nick} = $3; $hash{newjoin} = $3; }elsif (($4.$5) eq 'settopic') { my $newtopic; if ($8 and $7 and $6) { $newtopic = $6.$7.$8; } elsif ($7 and $6) { $newtopic = $6.$7; } else { $newtopic = $6; } $hash{newtopic} = $newtopic; }elsif (($4.$5.$6.$7) eq 'isnowknownas') { $hash{nick} = $3; $hash{newnick} = $8; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/irssi.pm0000774000076400007650000000401611705647720017603 0ustar wadewadepackage Pisg::Parser::Format::irssi; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+):\d+[^<*^!]+<[@%+~& ]?([^>]+)> (.*)', actionline => '^(\d+):\d+[^ ]+ +\* (\S+) (.*)', thirdline => '^(\d+):(\d+)[^-]+-\!- (\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'waskicked') { $hash{kicker} = $8; $hash{kicker} =~ m/by (\S+)/; $hash{kicker} = $1; } elsif ($4 eq 'changed') { $hash{newtopic} = $8; $hash{newtopic} =~ m/to:(.*)/; $hash{newtopic} = $1; } elsif (substr($3, 0, 5) eq 'mode/') { $hash{newmode} = substr($4, 1); $hash{nick} = $8 || $7; $hash{nick} =~ s/.* (\S+)$/$1/; # Get the last word of the string # when autorealname.pl is loaded, "has joined" moves to $6 $7 } elsif (($5.$6) eq 'hasjoined' or ($6.$7) eq 'hasjoined') { $hash{newjoin} = $3; } elsif (($5.$6) eq 'nowknown') { if ($8 =~ /^\s+(\S+)/) { $hash{newnick} = $1; } } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/mIRC6hack.pm0000774000076400007650000000753011705647720020165 0ustar wadewadepackage Pisg::Parser::Format::mIRC6hack; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # To use this logging format, add the following to mIRC's remote script # section: =head1 mIRC script # 2004-11-21 by coaster alias me { if ($1) { .describe $active $1- echo $color(own) -qt $active ** $me $1- } else { echo $color(info) $active * /me: insufficient parameters } } on ^*:ACTION:*:*:{ echo $color(action) -lt $iif($chan,$chan,$nick) ** $nick $1- haltdef } =cut use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+:?\d*\] <([^>]+)> (.*)', actionline => '^\[(\d+):\d+:?\d*\] \*\* (\S+) (.+)', thirdline => '^\[(\d+):(\d+):?\d*\] \* (.+)' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{saying} = $3; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{saying} = $3; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines, $action) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; $hash{saying} = $3; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked' && ($line[$#line] =~ /\)$/)) { $hash{kicker} = $line[4]; } elsif ($#line >= 4 && ($line[1].$line[2]) eq 'werekicked' && ($line[$#line] =~ /\)$/)) { $hash{kicker} = $line[4]; $hash{nick} = $self->{cfg}{maintainer}; } elsif ($#line >= 4 && ($line[1] eq 'changes') && ($line[$#line] =~ /\'$/)) { $hash{newtopic} = join(' ', @line[4..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setsmode:') { $hash{newmode} = $line[3]; } elsif ($#line == 4 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($line[0] eq 'Joins:') { # Alt+O -> IRC -> Options -> Short join/parts $hash{newjoin} = $line[1]; } elsif ($#line == 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } elsif ($action) { if ( ($hash{saying} =~ /^Set by \S+ on \S+ \S+ \d+ \d+:\d+:\d+/) || ($hash{saying} =~ /^Now talking in #\S+/) || ($hash{saying} =~ /^Topic is \'.*\'/) || ($hash{saying} =~ /^Disconnected/) || ($hash{saying} =~ /^\S+ has quit IRC \(.+\)/) || ($hash{saying} =~ /^\S+ has left \#\S+/) || ($hash{saying} =~ /^\S+\s\S+ has left \#\S+/) || ($hash{saying} =~ /^\S+\s\S+ Quit \S+/) || ($hash{saying} eq "You're not channel operator") || ($hash{nick} eq 'Attempting' && $hash{saying} =~ /^to rejoin channel/) || ($hash{nick} eq 'Rejoined' && $hash{saying} =~ /^channel/) || ($hash{saying} =~ /^Retrieving #\S+ info\.\.\./) ) { return 0; } else { $hash{saying} =~ s/^\Q$hash{nick}\E //; return \%hash; } } else { return; } return \%hash unless ($action); } return; } 1; pisg-0.73/modules/Pisg/Parser/Format/oer.pm0000774000076400007650000000425211705647720017241 0ustar wadewadepackage Pisg::Parser::Format::oer; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; use POSIX qw(strftime); $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+)\s+:([^!]+)[^ ]+ PRIVMSG (\#[^ ]+) :([^\001].*)', actionline => '^(\d+)\s+:([^!]+)[^ ]+ PRIVMSG (\#[^ ]+) :\001ACTION (.*)', thirdline => '^(\d+)\s+:([^!]+)[^ ]+ ([A-Z]+) (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = strftime "%H", localtime($1); $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = strftime "%H", localtime($1); $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; my $tmp; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = strftime "%H", localtime($1); $hash{min} = strftime "%M", localtime($1); $hash{nick} = $2; my @arr = split(" ", $4); if ($3 eq 'KICK' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $hash{kicker} = $hash{nick}; $hash{nick} = $arr[1]; } elsif ($3 eq 'TOPIC' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $tmp = join(" ", @arr[1..$#arr]); $tmp =~ s/^://; $hash{newtopic} = $tmp; } elsif ($3 eq 'MODE' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $hash{newmode} = $arr[1]; } elsif ($3 eq 'JOIN' && lc($arr[0]) eq ":".lc($self->{cfg}->{channel})) { $hash{newjoin} = $3; } elsif ($3 eq 'NICK') { $arr[0] =~ s/^://; $hash{newnick} = $arr[0]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/mIRC.pm0000774000076400007650000000372211705647720017247 0ustar wadewadepackage Pisg::Parser::Format::mIRC; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+\S+ <([^>]+)> (.*)$', actionline => '^\[(\d+):\d+\S+ \* (\S+) (.*)$', thirdline => '^\[(\d+):(\d+)\S+ \*{3} (.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{saying} = $3; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{saying} = $3; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked') { $hash{kicker} = $line[4]; } elsif ($#line >= 4 && ($line[1] eq 'changes')) { $hash{newtopic} = join(' ', @line[4..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setsmode:') { $hash{newmode} = $line[3]; } elsif ($#line >= 3 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($#line >= 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/pircbot.pm0000774000076400007650000000751411705647720020122 0ustar wadewadepackage Pisg::Parser::Format::pircbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $ctcpchr = chr(1); my $self = { cfg => $args{cfg}, normalline => '^(\d+)\s:([^!]+)![^@]+@\S+\sPRIVMSG\s([#&+!]\S+)\s:([^' . $ctcpchr . '].*)$' . '|' . '^(\d+)\s(>>>)PRIVMSG\s([#&+!]\S+)\s:([^' . $ctcpchr . '].*)$', actionline => '^(\d+)\s:([^!]+)![^@]+@\S+\sPRIVMSG\s([#&+!]\S+)\s:' . $ctcpchr . 'ACTION (.+)' . $ctcpchr . '\s*$' . '|' . '^(\d+)\s(>>>)PRIVMSG\s([#&+!]\S+)\s:' . $ctcpchr . 'ACTION (.+)' . $ctcpchr . '\s*$', thirdline => '^(\d+)\s:([^!]+)![^@]+@\S+\s(.+)$' . '|' . '^(\d+)\s(>>>)([^P].+)$', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { if (defined($8)) { return unless (lc($7) eq lc($self->{cfg}->{channel})); my @time = localtime($5 / 1000); $hash{hour} = $time[2]; $hash{nick} = $6; $hash{saying} = $8; } else { return unless (lc($3) eq lc($self->{cfg}->{channel})); my @time = localtime($1 / 1000); $hash{hour} = $time[2]; $hash{nick} = $2; $hash{saying} = $4; } $hash{nick} = $self->{cfg}->{maintainer} if ($hash{nick} eq '>>>'); return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { if (defined($8)) { return unless (lc($7) eq lc($self->{cfg}->{channel})); my @time = localtime($5 / 1000); $hash{hour} = $time[2]; $hash{nick} = $6; $hash{saying} = $8; } else { return unless (lc($3) eq lc($self->{cfg}->{channel})); my @time = localtime($1 / 1000); $hash{hour} = $time[2]; $hash{nick} = $2; $hash{saying} = $4; } $hash{nick} = $self->{cfg}->{maintainer} if ($hash{nick} eq '>>>'); return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my ($time, @line); if (defined($6)) { my @time = localtime($4 / 1000); $hash{hour} = $time[2]; $hash{min} = $time[1]; $hash{nick} = $self->{cfg}->{maintainer}; @line = split(/\s+/, $6); } else { my @time = localtime($1 / 1000); $hash{hour} = $time[2]; $hash{min} = $time[1]; $hash{nick} = $2; @line = split(/\s+/, $3); } if ($line[0] eq 'KICK') { return unless (lc($line[1]) eq lc($self->{cfg}->{channel})); $hash{kicker} = $hash{nick}; $hash{nick} = $line[2]; } elsif ($line[0] eq 'TOPIC') { return unless (lc($line[1]) eq lc($self->{cfg}->{channel})); $hash{newtopic} = join(' ', @line[2..$#line]); $hash{newtopic} =~ s/^://; } elsif ($line[0] eq 'MODE') { return unless (lc($line[1]) eq lc($self->{cfg}->{channel})); $hash{newmode} = join(' ', @line[2..$#line]); } elsif ($line[0] eq 'JOIN') { return unless (lc($line[1]) eq ':' . lc($self->{cfg}->{channel})); $hash{newjoin} = $hash{nick}; } elsif ($line[0] eq 'NICK') { $hash{newnick} = $line[1]; $hash{newnick} =~ s/^://; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/axur.pm0000774000076400007650000000342511705647720017434 0ustar wadewadepackage Pisg::Parser::Format::axur; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[\d+/\d+/\d+ @ (\d+):\d+:\d+\] [\>\(|<]+([^>\s]+)[\)|>]\s+(.*)', actionline => '^\[\d+/\d+/\d+ @ (\d+):\d+:\d+\] \*\s+(\S+) (.*)', thirdline => '^\[\d+/\d+/\d+ @ (\d+):(\d+):\d+\] \*\*\*\s+(\S+) (\S+) (\S+) (\S+) (\S+) (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'haskicked') { $hash{kicker} = $3; $hash{nick} = $6; } elsif (($4.$5) eq 'haschanged') { $hash{newtopic} = $8; } elsif (($7) eq '+o') { $hash{newmode} = '+o'; } elsif (($7) eq '-o') { $hash{newmode} = '-o'; } elsif (($4.$5) eq 'hasjoined') { $hash{newjoin} = $3; } elsif ((($4.$5) eq 'nowknown') || (($4.$5) eq 'nowknow')) { $hash{newnick} = $7; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/IRCAP.pm0000774000076400007650000001226311705647720017313 0ustar wadewadepackage Pisg::Parser::Format::IRCAP; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # Modifications to parse IRCAP 7.5 logs, made by Armando Camarero, September 2003. # This file is a modification of the mIRC6 parser file included in Pisg 0.49. # Copyright (C) 2003 Armando Camarero # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # To see this script working visit http://arcepi.hn.org/ED/ (statistics aren't online 24x7 - hosted at my computer...) # Sorry if the script isn't too clean, it is the first thing I programmed (I also learnt Perl doing this), but I can say # it works perfectly. # This script needs log timestamp to be enabled in mIRC: File -> Options -> IRC: Logging and mark Timestamp logs. use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+:?\d*\] <([^>]+)> (.*)', thirdline => '^\[(\d+):(\d+):?\d*\] (\*\*\*|\*) (.+)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; return $self->thirdline($line, $lines, 1); } sub thirdline { my ($self, $line, $lines, $action) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); my @linea = split (/\s/, $line); $hash{hour} = $1; $hash{min} = $2; $hash{saying} = $3; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#linea >= 2 and $linea[2] eq 'topic:') { #print $linea[2], "\n"; } if ($#linea >= 7 && ($linea[3].$linea[4]) eq 'hasido') { $hash{kicker} = $linea[7]; $hash{nick} = $linea[2]; my $razon = join (' ', @linea[8..$#linea]); $razon =~ s/(\(|\))//g; $hash{kicktext} = $razon; #print "kick detectado: $linea[7] kickeo a $linea[2], razón $razon\n"; } elsif ($#line >= 4 && ($line[1].$line[2]) eq 'werekicked' && ($line[$#line] =~ /\)$/)) { $hash{kicker} = $line[4]; $hash{nick} = $self->{cfg}{maintainer}; } elsif ($#linea >= 4 && ($linea[2] eq 'topic:')) { $hash{newtopic} = join(' ', @linea[5..$#linea]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; $hash{nick} = $linea[3]; } elsif ($#linea >= 5 && $linea[2] eq 'modo:') { #print "Cambio de modo detectado\n"; $linea[5] =~ s/\[//g; $linea[6] =~ s/\]//g; #print $linea[6], "\n"; $hash{newmode} = $linea[5]; # newmode es +o -o etc.... $hash{modechanges} = $linea[6]; # modechanges es el nick al que se le da/quita la @ $hash{nick} = $linea[3]; # nick, como siempre, es el que la da. } elsif ($#linea == 7 && $linea[6] eq 'entra') { #print "Entrada al canal detectada de $linea[2]\n"; $hash{newjoin} = $linea[2]; $hash{nick} = $linea[2]; } elsif ($#linea == 5 && ($linea[3].$linea[4]) eq 'esahora') { #print "Cambio de nick detectado\n"; $hash{newnick} = $linea[5]; $hash{nick} = $linea[2]; } elsif ($action) { $line =~ s/^\[(\d+):(\d+):?\d*\] \* //; $hash{saying} = $line; my @nick = split (' ', $hash{saying}); $hash{nick} = $nick[0]; #print $line, "\n"; #print $hash{saying}, "\n"; if ( ($hash{saying} =~ /^Set by \S+ on \S+ \S+ \d+ \d+:\d+:\d+/) || ($hash{saying} =~ /^Now talking in #\S+/) || ($hash{saying} =~ /^Topic is \'.*\'/) || ($hash{saying} =~ /^Disconnected/) || ($hash{saying} =~ /^\S+ has quit IRC \(.+\)/) || ($hash{saying} =~ /^\S+ has left \#\S+/) || ($hash{saying} eq "You're not channel operator") || ($hash{nick} eq 'Attempting') || ($hash{nick} eq 'Rejoined') || ($hash{saying} =~ /^Retrieving #\S+ info\.\.\./) || ($hash{saying} =~ /^\[/) ) { #print "$hash{saying} No es una ACCION\n"; return 0; } else { #print "Detectada una ACCION: $hash{saying}\n"; #print $nick[0], "\n"; $hash{saying} =~ s/^\Q$hash{nick}\E //; return \%hash; } } else { return; } return \%hash unless ($action); } return; } 1; pisg-0.73/modules/Pisg/Parser/Format/RacBot.pm0000774000076400007650000000516611705647720017633 0ustar wadewadepackage Pisg::Parser::Format::RacBot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+:\d+\]\s+<([^>]+)> (.*)', actionline => '^\[(\d+):\d+:\d+\]\s+\*(\S+)\s+(.*)', thirdline => '^\[(\d+):(\d+):\d+\]\s+([^-\$!#].*)', }; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; my @line = split /\s+/, $3; if ($#line >= 5 && $line[1].$line[2].$line[3] eq 'hasbeenkicked') { ($hash{kicker} = $line[5]) =~ s/!.*$//; ($hash{nick} = $line[0]) =~ s/!.*$//; } elsif ($line[0].$line[1] eq 'Topicchanged') { if ($line[2] eq 'to') { $hash{newtopic} = join ' ', @line[3 .. ($#line-2)]; $hash{newtopic} =~ s/^"//; $hash{newtopic} =~ s/"$//; ($hash{nick} = $line[$#line]) =~ s/!.*$//; } elsif ($line[2] eq 'on') { $hash{newtopic} = join ' ', @line[7 .. $#line]; $hash{newtopic} =~ s/^"//; $hash{newtopic} =~ s/"$//; ($hash{nick} = $line[5]) =~ s/!.*$//; } else { return; } } elsif ($#line >= 4 && $line[2].$line[3] eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($#line >= 5 && $line[1].$line[2].$line[3].$line[4] eq 'isnowknownas') { $hash{newnick} = $line[5]; $hash{nick} = $line[0]; } elsif ($line[0].$line[$#line-1] eq 'MODEby') { ($hash{nick} = $line[$#line]) =~ s/!.*$//; $hash{newmode} = $line[1]; $hash{newmode} =~ s/^"//; } else { return; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/muh2.pm0000774000076400007650000000432111705647720017324 0ustar wadewadepackage Pisg::Parser::Format::muh2; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # This Parser works with muh version muh-2.1 and above. # muh got a new log-format, so this is version 2 # contact: boitl @ IRC, sebastian@mquant.de, 09/2003 # note: # muh-2.1 is buggy in action-loggin. # apply http://www.mquant.de/downloads/muh-actionpatch.diff use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+\S+ <([^>]+)> (.*)$', actionline => '^\[(\d+):\d+\S+ \* (\S+) (.*)$', thirdline => '^\[(\d+):(\d+)\S+ \*{3} (.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked') { $hash{kicker} = $line[4]; } elsif ($#line >= 4 && ($line[1] eq 'changes')) { $hash{newtopic} = join(' ', @line[4..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setsmode') { $hash{newmode} = $line[3]; } elsif ($#line >= 3 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($#line >= 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/grufti.pm0000774000076400007650000000337311705647720017757 0ustar wadewadepackage Pisg::Parser::Format::grufti; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+\] <([^>]+)> (.*)', actionline => '^\[(\d+):\d+\] \* (\S+) (.*)', thirdline => '^\[(\d+):(\d+)\] (\S+) (\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($5 eq 'kicked') { $hash{kicker} = $3; $hash{nick} = $6; } elsif (($4.$5) eq 'haschanged') { $hash{newtopic} = $9; } elsif (($4.$5) eq 'modechange') { $hash{newmode} = substr($6, 1); $hash{nick} = $9; $hash{nick} =~ /.*[by ](\S+)/; $hash{nick} = $1; } elsif ($5 eq 'joined') { $hash{newjoin} = $1; } elsif (($3.$4) eq 'Nickchange') { $hash{nick} = $7; $hash{newnick} = $9; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/ircII.pm0000774000076400007650000000600211705647720017446 0ustar wadewadepackage Pisg::Parser::Format::ircII; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # Parser for logs from ircII # by James Andrewartha # based on Template.pm and Trillian.pm # Note that you will need some triggers similar to these in your .ircrc to get # timestamping: # on #^timer 50 "*0" echo $0 # on #^timer 50 "*5" echo $0 # Known issues: the time of topic changes is only as accurate as the time- # stamping (the above lines provide 5-minute accuracy). use strict; $^W = 1; # Yes, global variables are bad. But they do need to be global to avoid pain. my ($global_hour, $global_minute); sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(<([^>]+)> (.*)|> (.*))', actionline => '^\* (\S+[^>]) (.*)', thirdline => '^((\d+):(\d+)|\*{3} (.+)|IRC log started \w+ \w+ \w+ (\d+:\d+))', }; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $global_hour; if ($1 =~ /^<([^>]+)> (.*)/) { $hash{nick} = $1; $hash{saying} = $2; } elsif ($1 =~ /^> (.*)/) { $hash{nick} = $self->{cfg}->{maintainer}; $hash{saying} = $1; } return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $global_hour; $hash{nick} = $1; $hash{saying} = $2; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { # Mainly stolen from Trillian.pm if ($1 =~ /^\*{3} (\S+) has been kicked off channel (\S+) by (\S+) .+/) { $hash{nick} = $1; $hash{kicker} = $3; } elsif ($1 =~ /^\*{3} (\S+) has changed the topic on channel (\S+) to (.+)/) { $hash{nick} = $1; $hash{newtopic} = $3; } elsif ($1 =~ /^\*{3} Mode change \"(\S+)[^\"]+\".+ by (.+)$/) { $hash{nick} = $2; $hash{newmode} = $1; } elsif ($1 =~ /^\*{3} (\S+) \S+ has joined channel \S+/) { $hash{nick} = $1; $hash{newjoin} = $1; } elsif ($1 =~ /^\*{3} (\S+) is now known as (\S+)/) { $hash{nick} = $1; $hash{newnick} = $2; } elsif ($1 =~ /^(\d+):(\d+)$/) { $global_hour = $1; $global_minute = $2; } elsif ($1 =~ /^IRC log started \w+ \w+ \w+ (\d+):(\d+)/) { $global_hour = $1; $global_minute = $2; } $hash{hour} = $global_hour; $hash{min} = $global_minute; return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/dancer.pm0000774000076400007650000000333511705647720017711 0ustar wadewadepackage Pisg::Parser::Format::dancer; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+)\.\S+ \# \s+ <([^>]+)> (.*)', actionline => '^(\d+)\.\S+ \# \s+ \* (\S+) (.*)', thirdline => '^(\d+)\.(\d+)\.\S+ ([^#>* ]+)\s+ (.*)' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; if($3 eq 'Kick') { $4 =~ /\(\S+ (\S+) .*?\) by (\S+)\!/o; $hash{nick} = $1; $hash{kicker} = $2; } elsif($3 eq 'Topic') { $4 =~ /\"(.*)\" by (\S+) /o; $hash{newtopic} = $1; $hash{nick} = $2; } elsif($3 eq 'Mode') { $4 =~ /\S+ (\S+) .*\" by (\S+) /o; $hash{newmode} = $1; $hash{nick} = $2; } elsif($3 eq 'Join') { $4 =~ /(\S+) (\S+) /o; $hash{nick} = $1; $hash{newjoin} = $1; } elsif($3 eq 'Nick') { $4 =~ /(\S+) is now known as (\S+) /o; $hash{nick} = $1; $hash{newnick} = $2; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/bobot.pm0000774000076400007650000000314711705647720017563 0ustar wadewade# package for bobot parsing made by Oct@zoy.org package Pisg::Parser::Format::bobot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[[^-]+- ([^:]+):[^\]]+\] <([^>]+)> (.*)$', actionline => '^\[[^-]+- ([^:]+):[^\]]+\] \* ([^ ]+) (.*)$', thirdline => '^\[[^-]+- ([^:]+):([^\]]+)\] \*\*\* ([^ ]+) \[[^\]]+\] (.*)$', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if($4 =~ /^topic ([^ ]+) \((.*)\)$/) { $hash{newtopic}= $2; } elsif($4 =~ /^mode ([\+-]o+) (.*)$/) { $hash{newmode} = $1; $hash{nick} = $2; } elsif($4 =~/^kick ([^ ]+) .*$/) { $hash{kicker} = $hash{nick}; $hash{nick} = $1; } elsif($4 =~/^join .*$/) { $hash{newjoin} = $hash{nick}; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/Vision.pm0000774000076400007650000000406011705647720017720 0ustar wadewadepackage Pisg::Parser::Format::Vision; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+\S+ <([^>]+)> (.*)$', actionline => '^\[(\d+):\d+\S+ \* (\S+) (.*)$', thirdline => '^\[(\d+):(\d+)\S+ \*{3} (.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#line >= 7 && ($line[1].$line[2].$line[3]) eq 'hasbeenkicked') { $hash{kicker} = $line[7]; } elsif ($#line >= 4 && ($line[1].$line[2] eq 'Topicchanged')) { $hash{newtopic} = join(' ', @line[5..$#line]); ($hash{nick} = $line[4]) =~ s/^[@%\+~&]//o; # Remove prefix $hash{nick} =~ s/:$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setmode') { $hash{newmode} = $line[3]; } elsif ($#line >= 3 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($#line >= 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; $hash{newnick} =~ s/\.$//; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/dircproxy.pm0000774000076400007650000000555311705647720020504 0ustar wadewadepackage Pisg::Parser::Format::dircproxy; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^<([^!]+)![^>]+>\s\[(\d{2}):\d{2}\]\s(.+)$', actionline => '^\[([^!]+)![^\]]+\]\s\[(\d{2}):\d{2}\]\sACTION\s(.+)$', thirdline => '^\-(\S+)\-\s\[(\d{2}:\d{2})\]\s(.+)$', normalline_old => '^@(\d+)\s<([^!]+)![^>]+>\s(.+)$', actionline_old => '^@(\d+)\s\[([^!]+)![^\]]+\]\sACTION\s(.+)$', thirdline_old => '^@(\d+)\s\S+\s(.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $2; $hash{nick} = $1; $hash{saying} = $3; return \%hash; } elsif ($line =~ /$self->{normalline_old}/o) { $hash{hour} = (localtime($1))[2]; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $2; $hash{nick} = $1; $hash{saying} = $3; return \%hash; } elsif ($line =~ /$self->{actionline_old}/o) { $hash{hour} = (localtime($1))[2]; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; my @word; if ($line =~ /$self->{thirdline}/o) { return if ($1 eq 'dircproxy'); @word = split(/\s+/, $3); my @time = split(/:/, $2); $hash{hour} = $time[0]; $hash{min} = $time[1]; } elsif ($line =~ /$self->{thirdline_old}/o) { return if ($1 eq 'dircproxy'); @word = split(/\s+/, $2); $hash{hour} = (localtime($1))[2]; $hash{min} = (localtime($1))[1]; } else { return; } # the real parser here for thirdline... $hash{nick} = $word[0]; if (defined($word[3]) && $word[0] eq 'Kicked') { $hash{kicker} = $word[3]; $hash{nick} = $self->{cfg}->{maintainer}; } elsif (defined($word[4]) && $word[1] eq 'kicked') { $hash{kicker} = $word[4]; } elsif (defined($word[3]) && $word[2] eq 'changed') { if ($word[3] eq 'mode:') { $hash{newmode} = join(' ', @word[4..$#word]); } elsif ($word[3] eq 'topic:') { $hash{newtopic} = join(' ', @word[4..$#word]); } } elsif (defined($word[2]) && $word[2] eq 'joined') { $hash{newjoin} = $hash{nick}; } # elsif ($word[0] eq 'NICK') { # $hash{newnick} = $word[1]; # $hash{newnick} =~ s/^://; #} return \%hash; } 1; pisg-0.73/modules/Pisg/Parser/Format/Trillian.pm0000774000076400007650000000457111705647720020236 0ustar wadewadepackage Pisg::Parser::Format::Trillian; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # old format: # [hh:mm] says something # new v3 format: # [hh:mm] nick: says something use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+[^ ]+ ]+)[^ ]+ (.*)', actionline => '^\[(\d+):\d+[^ ]+ \* (\S+) (.*)', thirdline => '^\[(\d+):(\d+)[^ ]+ \*{3}\s(.+)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; $hash{saying} =~ s/\(Link: (((http|https|ftp|telnet|news):\/\/|).*?)\)\1/$1/; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; $hash{saying} =~ s/\(Link: (((http|https|ftp|telnet|news):\/\/|).*?)\)\1/$1/; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $3) =~ s/^[@%\+~&]//o; # Remove prefix if ($3 =~ /^(\S+) has been kicked off channel (\S+) by (\S+) .+/) { ($hash{nick} = $1) =~ s/^[@%\+~&]//o; # Remove prefix $hash{kicker} = $3; } elsif ($3 =~ /^(\S+) has changed the topic on channel (\S+) to (.+)/) { ($hash{nick} = $1) =~ s/^[@%\+~&]//o; # Remove prefix $hash{newtopic} = $3; } elsif ($3 =~ /^Mode change \"(\S+)[^\"]+\".+ by (.+)$/) { ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{newmode} = $1; } elsif ($3 =~ /^(\S+) \S+ has joined channel \S+/) { $hash{nick} = $1; $hash{newjoin} = $1; } elsif ($3 =~ /^(\S+) is now known as (\S+)/) { ($hash{nick} = $1) =~ s/^[@%\+~&]//o; # Remove prefix $hash{newnick} = $2; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/mozbot.pm0000774000076400007650000000476611705647720020000 0ustar wadewadepackage Pisg::Parser::Format::mozbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # This is a parser for Mozbot's XMLLogger module, NOT the standard logs! # File amended from Template.pm by Adam "Fatman" Richardson use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '(.+)', actionline => '(.+)', thirdline => '<(.+) channel="#.+" nick="(.+)" time="(.+)">(.*)', }; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { my $time = $2; $hash{nick} = $1; $hash{saying} = convert($3); $time =~ /T(\d\d)/; $hash{hour} = int($1); return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { my $time = $2; $hash{nick} = $1; $hash{saying} = convert($3); $time =~ /T(\d\d)/; $hash{hour} = int($1); return \%hash; } else { return; } } # Parses the 'third' line - (the third line is everything else, like # topic changes, mode changes, kicks, etc.) sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my $time = $3; my $act = $1; my $nick = $2; my $doing = convert($4); $time =~ /T(\d\d):(\d\d)/; $hash{hour} = int($1); $hash{min} = int($2); $hash{nick} = $nick; if ($act eq 'kick') { $hash{nick} = $doing; $hash{kicker} = $nick; $hash{kicktext} = ''; } elsif ($act eq 'mode') { $hash{newmode} = $doing; } elsif ($act eq 'join') { $hash{newjoin} = $nick; } elsif ($act eq 'topic') { $hash{newtopic} = $doing; } return \%hash; } else { return; } } # Convert XML-entities sub convert { my $string = shift; $string =~ s/'/\'/g; $string =~ s/"/\"/g; $string =~ s/>/>/g; $string =~ s/</ $args{cfg}, normalline => '^\[[^\]]*(\d{2}):\d+:\d+\] <([^>]+)> (.*)$', actionline => '^\[[^\]]*(\d{2}):\d+:\d+\] \* (\S+) (.*)$', thirdline => '^\[[^\]]*(\d{2}):(\d+):\d+\] \*{3} (.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $line[0]; if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked') { $hash{kicker} = $line[4]; $hash{kicktext} = $3; $hash{kicktext} =~ s/^[^\(]+\((.+)\)$/$1/; } elsif ($#line >= 4 && ($line[1].$line[2]) eq 'changestopic') { $hash{newtopic} = join(' ', @line[4..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 4 && ($line[1].$line[2]) eq 'setsmode:') { $hash{newmode} = $line[3]; $hash{modechanges} = join(" ", splice(@line, 4)); } elsif ($#line >= 1 && $line[0] eq 'Joins:') { $hash{nick} = $line[1]; $hash{newjoin} = $line[1]; } elsif ($#line >= 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/javabot.pm0000774000076400007650000000317711705647720020107 0ustar wadewadepackage Pisg::Parser::Format::javabot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '(\d+):\d+:\d+ <([^>\s]+)>\s+(.*)', actionline => '(\d+):\d+:\d+ \*{1,}\s+(\S+) (.*)', thirdline => '(\d+):(\d+):\d+ [<-]-[->]\s+(\S+) (\S+) (\S+) (\S+) (\S+) ?(\S+)? ?(.*)?', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'haskicked') { $hash{kicker} = $3; $hash{nick} = $6; } elsif (($4.$5) eq 'haschanged') { $hash{newtopic} = $9; } elsif (($4.$5) eq 'setsmode') { $hash{newmode} = $6; } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $1; } elsif (($5.$6) eq 'isknown') { $hash{newnick} = $8; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/mIRC6.pm0000774000076400007650000000647611705647720017346 0ustar wadewadepackage Pisg::Parser::Format::mIRC6; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # NOTE: mIRC6's logging format is severly damaged by design. Try to use the # "mIRC6hack" format instead. use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+:?\d*\] <([^>]+)> (.*)', thirdline => '^\[(\d+):(\d+):?\d*\] \* (.+)' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{saying} = $3; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; return $self->thirdline($line, $lines, 1); } sub thirdline { my ($self, $line, $lines, $action) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; $hash{saying} = $3; ($hash{nick} = $line[0]) =~ s/^[@%\+~&]//o; # Remove prefix if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked' && ($line[$#line] =~ /\)$/)) { $hash{kicker} = $line[4]; } elsif ($#line >= 4 && ($line[1].$line[2]) eq 'werekicked' && ($line[$#line] =~ /\)$/)) { $hash{kicker} = $line[4]; $hash{nick} = $self->{cfg}{maintainer}; } elsif ($#line >= 4 && ($line[1] eq 'changes') && ($line[$#line] =~ /\'$/)) { $hash{newtopic} = join(' ', @line[4..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setsmode:') { $hash{newmode} = $line[3]; } elsif ($#line == 4 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($line[0] eq 'Joins:') { # Alt+O -> IRC -> Options -> Short join/parts $hash{newjoin} = $line[1]; } elsif ($#line == 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } elsif ($action) { if ( ($hash{saying} =~ /^Set by \S+ on \S+ \S+ \d+ \d+:\d+:\d+/) || ($hash{saying} =~ /^Now talking in #\S+/) || ($hash{saying} =~ /^Topic is \'.*\'/) || ($hash{saying} =~ /^Disconnected/) || ($hash{saying} =~ /^\S+ has quit IRC \(.+\)/) || ($hash{saying} =~ /^\S+ has left \#\S+/) || ($hash{saying} =~ /^\S+\s\S+ has left \#\S+/) || ($hash{saying} =~ /^\S+\s\S+ Quit \S+/) || ($hash{saying} eq "You're not channel operator") || ($hash{nick} eq 'Attempting' && $hash{saying} =~ /^to rejoin channel/) || ($hash{nick} eq 'Rejoined' && $hash{saying} =~ /^channel/) || ($hash{saying} =~ /^Retrieving #\S+ info\.\.\./) ) { return 0; } else { $hash{saying} =~ s/^\Q$hash{nick}\E //; return \%hash; } } else { return; } return \%hash unless ($action); } return; } 1; pisg-0.73/modules/Pisg/Parser/Format/zcbot.pm0000774000076400007650000000411511705647720017573 0ustar wadewadepackage Pisg::Parser::Format::zcbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^[^ ]+ (\d+):[^ ]+ :([^!]+)[^ ]+ PRIVMSG (\#[^ ]+) :([^\001].*)', actionline => '^[^ ]+ (\d+):[^ ]+ :([^!]+)[^ ]+ PRIVMSG (\#[^ ]+) :\001ACTION (.*)', thirdline => '^[^ ]+ (\d+):(\d+):\d+ :([^!]+)[^ ]+ ([A-Z]+) (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; my $tmp; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; my @arr = split(" ", $5); if ($4 eq 'KICK' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $hash{kicker} = $hash{nick}; $hash{nick} = $arr[1]; } elsif ($4 eq 'TOPIC' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $tmp = join(" ", @arr[1..$#arr]); $tmp =~ s/^://; $hash{newtopic} = $tmp; } elsif ($4 eq 'MODE' && lc($arr[0]) eq lc($self->{cfg}->{channel})) { $hash{newmode} = $arr[1]; } elsif ($4 eq 'JOIN' && lc($arr[0]) eq ":".lc($self->{cfg}->{channel})) { $hash{newjoin} = $3; } elsif ($4 eq 'NICK') { $arr[0] =~ s/^://; $hash{newnick} = $arr[0]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/moobot.pm0000774000076400007650000000370411705647720017754 0ustar wadewadepackage Pisg::Parser::Format::moobot; use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\d{4}-\d{2}-\d{2} (\d{2}):\d{2}:\d{2} :([^! ]+)(?:![^ ]+)? PUBMSG ([^ ]+) :(.*)', actionline => '^\d{4}-\d{2}-\d{2} (\d{2}):\d{2}:\d{2} :([^! ]+)(?:![^ ]+)? CTCP ([^ ]+) :ACTION (.*)', thirdline => '^\d{4}-\d{2}-\d{2} (\d{2}):(\d{2}):\d{2} :([^! ]+)(?:![^ ]+)? ([^ ]+) :?([^ ]+) ?(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o and lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o and lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o and lc($5) eq ($self->{cfg}->{channel})) { my $args = $6; $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($4 eq "KICK") { $hash{kicker} = $3; $args =~ /^([^ ]+)/; $hash{nick} = $1; } elsif ($4 eq "TOPIC") { $args =~ s/^://; $hash{newtopic} = $args; } elsif ($4 eq "MODE") { $hash{newmode} = $args; } elsif ($4 eq "JOIN") { $hash{newjoin} = $3; } return \%hash; # Nick changes do not have an associated channel. } elsif ($line =~ /$self->{thirdline}/o and $4 eq "NICK") { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; $hash{newnick} = $5; return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/mbot.pm0000774000076400007650000000334311705647720017415 0ustar wadewadepackage Pisg::Parser::Format::mbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\S+ \S+ [ \d]\d (\d+):\d+:\d+ \d+ <([^>]+)> (?!\001ACTION)(.*)', actionline => '^\S+ \S+ [ \d]\d (\d+):\d+:\d+ \d+ <([^>]+)> \001ACTION (.*)\001$', thirdline => '^\S+ \S+ [ \d]\d (\d+):(\d+):\d+ \d+ (\S+) (\S+) ?(\S*) ?(\S*) ?(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($4 eq 'KICK') { $hash{kicker} = $3; $hash{nick} = $5; } elsif ($4 eq 'TOPIC') { $hash{newtopic} = $5." ".$6." ".$7; } elsif ($4 eq 'MODE') { $hash{newmode} = $5; } elsif ($4 eq 'JOIN') { $3 =~ /^([^!]+)!/; $hash{newjoin} = $1; $hash{nick} = $1; } elsif ($4 eq 'NICK') { $hash{newnick} = $5; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/perlbot.pm0000774000076400007650000000330411705647720020120 0ustar wadewadepackage Pisg::Parser::Format::perlbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+):\d+:\d+[^ ]+ <([^>]+)> (.*)', actionline => '^(\d+):\d+:\d+[^ ]+ \* (\S+) (.*)', thirdline => '^(\d+):(\d+):\d+[^ ]+ (\S+) (\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $4) =~ s/^[@%\+~&]//o; # Remove prefix if (($3) eq '[KICK]') { $hash{kicker} = $8; } elsif ($3 eq '[TOPIC]') { $hash{newtopic} = "$5 $6 $7 $8 $9"; } elsif (($3) eq '[MODE]') { $hash{newmode} = $7; } elsif (($5) eq 'joined') { $hash{newjoin} = $3; } elsif (($3) eq '[NICK]') { $hash{newnick} = $8; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/weechat.pm0000774000076400007650000000365011705647720020075 0ustar wadewadepackage Pisg::Parser::Format::weechat; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\d+ \S+ \d+ (\d+):\d+[^<]+<([^>]+)> (.*)', actionline => '^\d+ \S+ \d+ (\d+):\d+:\d+ -\*- (\S+) (.*)', thirdline => '^\d+ \S+ \d+ (\d+):(\d+):\d+ (?:-=-|<--|-->) (\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'haskicked') { $hash{nick} = $6; $hash{kicker} = $3; } elsif ($4.$5.$6 eq 'haschangedtopic') { $hash{newtopic} = $8; $hash{newtopic} =~ m/to:(.*)/; $hash{newtopic} = $1; } elsif ($3 eq 'Mode') { $hash{newmode} = substr($5, 1); $hash{nick} = $8 || $7; $hash{nick} =~ s/.* (\S+)$/$1/; # Get the last word of the string } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $3; } elsif (($5.$6) eq 'nowknown') { if ($8 =~ /^\s+(\S+)/) { $hash{newnick} = $1; } } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/konversation.pm0000774000076400007650000000400411705647720021171 0ustar wadewadepackage Pisg::Parser::Format::konversation; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[[^\[]+\[(\d+)[^\]]+\]\s+<([^>]+)>\s+(.*)$', actionline => '^\[[^\[]+\[(\d+)[^\]]+\]\s+\*\s(\S+)\s(.*)$', thirdline => '^\[[^\[]+\[(\d+):(\d+)[^\]]+\]\s(\S+)\s+(\S+)\s(.*)$', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $4; if ($4 eq 'You') { # Hack to remove You as a nick $hash{nick} = $self->{cfg}->{maintainer}; } if ($3 eq 'Mode') { $hash{newmode} = $5; $hash{newmode} =~ s/^[^+-]*//; } elsif ($3 eq 'Join') { $hash{newjoin} = $4; } elsif ($3 eq 'Nick') { $hash{newnick} = $5; $hash{newnick} =~ s/^.*\s+(\S+)$/$1/; } elsif ($3 eq 'Kick') { if ($5 =~ /^have kicked (\S+) from the channel \((.+)\).$/ ) { $hash{kicker} = $hash{nick}; $hash{nick} = $1; $hash{kicktext} = $2; } elsif ($5 =~ /^has been kicked from the channel by (\S+) \((.+)\).$/ ) { $hash{kicker} = $1; $hash{kicktext} = $2; } else { return; } } elsif ($3 eq 'Topic') { if ($5 =~ /the channel topic to "(.*)"\.$/) { $hash{newtopic} = $1; } else { return; } } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/psybnc.pm0000774000076400007650000000331111705647720017745 0ustar wadewadepackage Pisg::Parser::Format::psybnc; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\d+-\d+-\d+-(\d+)-\d+-\d+:[^:]+::([^!]+)[^:]+ PRIVMSG [^:]+:([^\001]+)', actionline => '^\d+-\d+-\d+-(\d+)-\d+-\d+:[^:]+::([^!]+)[^:]+:\001ACTION ([^\001]*)', thirdline => '^\d+-\d+-\d+-(\d+)-(\d+)-\d+:[^:]+::([^! .]+)[^ ]* (\w+) \S+ :?((\S*)\s*(.*))', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($4 eq 'KICK') { $hash{kicker} = $hash{nick}; $hash{nick} = $6; } elsif ($4 eq 'TOPIC') { $hash{newtopic} = $5; } elsif ($4 eq 'MODE') { $hash{newmode} = $6; } elsif ($4 eq 'JOIN') { $hash{newjoin} = $3; } elsif ($4 eq 'NICK') { # does this work? $hash{newnick} = $6; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/DCpp.pm0000774000076400007650000000651011705647720017301 0ustar wadewadepackage Pisg::Parser::Format::DCpp; use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[\d+\-\d+\-\d+\s(\d+):\d+\]\s+\<([^>]+)\> (.+)', actionline => '^NA', thirdline => '^\[\d+\-\d+\-\d+\s(\d+):(\d+)\]\s+\<([^>]+)\> (.+)', }; $self->{cfg}->{botnicks} .= ' Hub-Security'; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; if ($self->{cfg}->{botnicks} =~ /\b\Q$hash{nick}\E\b/) { return; } return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } # Parses the 'third' line - (the third line is everything else, like # topic changes, mode changes, kicks, etc.) # thirdline() has to return a hash with the following keys, for # every format: # hour - the hour we're in (for timestamp logging) # min - the minute we're in (for timestamp logging) # nick - the nick # kicker - the nick which kicked somebody (if any) # newtopic - the new topic (if any) # newmode - deops or ops, must be '+o' or '-o', or '+ooo' # newjoin - a new nick which has joined the channel # newnick - a person has changed nick and this is the new nick # # It should return a hash with the following (for formatting lines in html) # # kicktext - the kick reason (if any) # modechanges - data of the mode change ('Nick' in '+o Nick') # # The hash may also have a "repeated" key indicating the number of times # the line was repeated. (Used by eggdrops log for example.) sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; my $text = $4; my @line = split(/\s+/, $text); # Format-specific stuff goes here. if ($self->{cfg}->{botnicks} =~ /\b\Q$hash{nick}\E\b/) { if (lc($hash{nick}) eq 'hub-security') { if (defined $line[3] && $line[1].$line[2] eq 'isin') { $hash{newjoin} = $line[0]; $hash{nick} = $hash{newjoin}; } elsif (defined $line[6] && $line[3].$line[4] eq 'waskicked') { $hash{kicker} = $line[6]; $hash{nick} = $line[2]; } } return \%hash; } else { return; } } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/sirc.pm0000774000076400007650000000622211705647720017413 0ustar wadewadepackage Pisg::Parser::Format::sirc; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # parser for logs from sirc # based on module by bartko # the timestamps are needed for statistics generation # for timestamping use the timestep script for sirc # included in scripts/sirc-timestamp.pl use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '(\d+):\d+ <([^>\s]+)>\s+(.*)', actionline => '(\d+):\d+ \* (\S+) (.*)', thirdline => '(\d+):(\d+) \*(.)\* (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; if ($3 eq '>') { if ($4 =~ /^(\S+) \S+ has joined channel \S+$/) { $hash{newjoin} = $1; $hash{nick} = $1; } elsif ($4 =~ /^You have joined channel \S+$/) { $hash{newjoin} = $self->{cfg}->{maintainer}; $hash{nick} = $self->{cfg}->{maintainer}; } } elsif ($3 eq '<') { if ($4 =~ /^(\S+) has been kicked off channel \S+ by (\S+) \((.*)\)$/) { $hash{kicker} = $2; $hash{nick} = $1; $hash{kicktext} = $3; } elsif ($4 =~ /^You have been kicked off channel \S+ by (\S+)/) { $hash{kicker} = $1; $hash{nick} = $self->{cfg}->{maintainer}; $hash{kicktext} = $2; } } elsif ($3 eq 'T') { if ($4 =~ /^(\S+) has changed the topic on channel \S+ to \"(.+)\"$/) { $hash{newtopic} = $2; $hash{nick} = $1; } elsif ($4 =~ /^You have changed the topic on channel \S+ to \"(.+)\"$/) { $hash{newtopic} = $1; $hash{nick} = $self->{cfg}->{maintainer}; } elsif ($4 =~ /^Topic for \S+: (.+)$/) { $self->{topic_temp} = $1; } elsif ($self->{topic_temp} && ($4 =~ /^Topic for \S+ set by ([^!]+)!\S+/)) { $hash{nick} = $1; $hash{newtopic} = $self->{topic_temp}; delete $self->{topic_temp}; } } elsif ($3 eq '+' && ($4 =~ /^Mode change \"(\S+) ([^\"]+)\" on channel \S+ by (\S+)/)) { $hash{newmode} = $1; $hash{modechanges} = $2; $hash{nick} = $3; } elsif ($3 eq 'N' && ($4 =~ /^(S+) is now known as (S+)$/)) { $hash{nick} = $1; $hash{newnick} = $2; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/blootbot.pm0000774000076400007650000001150611705647720020300 0ustar wadewade# This is a template for blootbot logs http://blootbot.sf.net/ # hacked up by Tim Riker package Pisg::Parser::Format::blootbot; use strict; $^W = 1; # The 3 variables in the new subrountine, 'normalline', 'actionline' and # 'thirdline' represents regular expressions for extracting information from # the logfile. normalline is for lines where the person merely said # something, actionline is for lines where the person performed an action, # and thirdline matches everything else, including things like kicks, nick # changes, and op grants. See the thirdline subroutine for a list of # everything it should match. # blootbot puts hh:mm.ss at the start. # note that one log can contain more than one channel. # FIXME it would be nice if pisg would process them all in one pass! # # Normal lines are like: # # 01:02.03 normal # 01:02.03 * nick/#channel action sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d\d):\d\d\.\d\d <([^\/]+)\/(#[^>]+)> (.*)', actionline => '^(\d\d):\d\d\.\d\d \* (.*)/(#\S*) (.*)', thirdline => '^(\d\d):(\d\d)\.\d\d >>> (.*)', }; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o and lc $3 eq lc $self->{cfg}->{channel}) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{channel} = $3; $hash{saying} = $4; return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o and lc $3 eq lc $self->{cfg}->{channel}) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{channel} = $3; $hash{saying} = $4; return \%hash; } else { return; } } # Parses the 'third' line - (the third line is everything else, like # topic changes, mode changes, kicks, etc.) # thirdline() has to return a hash with the following keys, for # every format: # hour - the hour we're in (for timestamp logging) # min - the minute we're in (for timestamp logging) # nick - the nick # kicker - the nick which kicked somebody (if any) # newtopic - the new topic (if any) # newmode - deops or ops, must be '+o' or '-o', or '+ooo' # newjoin - a new nick which has joined the channel # newnick - a person has changed nick and this is the new nick # # It should return a hash with the following (for formatting lines in html) # # kicktext - the kick reason (if any) # modechanges - data of the mode change ('Nick' in '+o Nick') # # The hash may also have a "repeated" key indicating the number of times # the line was repeated. (Used by eggdrops log for example.) sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; # Format-specific stuff goes here. if ($3 =~ /^topic\/(#\S*) by (\S*) -> (.*)/) { # 01:02.03 >>> topic/#channel by nick -> topic... $hash{channel} = $1; $hash{nick} = $2; $hash{newtopic} = "$3"; } elsif ($3 =~ /^mode\/(#\S*) \[([\+\-]o*) (.*)\] by (\S*)/) { # 01:02.03 >>> mode/#channel [+o nick] by ChanServ $hash{channel} = $1; $hash{newmode} = $2; $hash{modechanges} = $3; $hash{nick} = $4; } elsif ($3 =~ /^join\/(#\S*) (\S*) \(\S*\)/) { # 01:02.03 >>> join/#channel nick (~user@example.com) $hash{channel} = $1; $hash{newjoin} = $2; } elsif ($3 =~ /^kick\/(#\S*) \[(\S*)!.*\] by (\S*) \((.*\))/) { # 01:02.03 >>> kick/#channel [nick!~user@example.com] by nick (reason) $hash{channel} = $1; $hash{nick} = $2; $hash{kicker} = $3; $hash{kicktext} = $4; } elsif ($3 =~ /^(\S*) materializes into (\S*)/) { # 01:02.03 >>> nick_ materializes into nick $hash{nick} = $1; $hash{newnick} = $2; # no channel so return now return \%hash; } return \%hash if ($hash{channel} and lc $hash{channel} eq lc $self->{cfg}->{channel}); return; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/supy.pm0000774000076400007650000000473611705647720017463 0ustar wadewadepackage Pisg::Parser::Format::supy; # pisg log parser for supybot bot # http://supybot.com/ # Copyright Jerome Kerdreux / Licence GPL # contact Jerome.Kerdreux@finix.eu.org for more information # This module supports both the old and new logformat (after 1.8.7) use strict; $^W = 1; sub new { my ($type, %args) = @_; my $timestamp = '\d+-[\d\w]+-\d+[ T](\d+):\d+:\d+'; my $thirdtimestamp = '\d+-[\d\w]+-\d+[ T](\d+):(\d+):\d+'; my $self = { cfg => $args{cfg}, # Old default timestamp format # [12-Feb-2004 16:59:42] plop # New default timestamp format # 2004-02-12T16:59:42 plop normalline => '^\[?'.$timestamp.']? <(\S+)> (.*)', # [05-Mar-2004 17:28:10] * Jkx|home bon je vais pas trainer .. actionline => '^\[?'.$timestamp.']? \* (\S+) (.*)', # [17-Feb-2004 08:13:47] *** Jkx changes topic to "Oh my god of topic" thirdline => '\[?'.$thirdtimestamp.']? \*\*\* (\S+) (\S+) (\S+) (\S+) ?(.*)?', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; # print "*** 1/$1 2/$2 3/$3 4/$4 5/$5 6/$6 7/$7 ***\n"; if (($4.$5) eq 'waskicked') { $hash{kicker} = $7; ($hash{kicktext} = $hash{kicker}) =~ s/\S+\s*//; $hash{kicker} =~ s/\s.*//; $hash{kicktext} =~ s/^\((.*)\)$/$1/; } elsif (($4.$5) eq 'changestopic') { $hash{newtopic} = $7; } elsif (($4.$5) eq 'setsmode:') { $hash{newmode} = $6; $hash{modechanges} = $7; } elsif (($4.$5) eq 'hasjoined') { $hash{newjoin} = $3; } elsif (($5.$6) eq 'nowknown') { $hash{newnick} = $7; $hash{newnick} =~ s/^as\s*//; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/Template.pm0000774000076400007650000000610011705647720020221 0ustar wadewade# This is a template for creating your own logfile parser. You can also look # in the other .pm files in this directory as good examples. package Pisg::Parser::Format::Template; use strict; $^W = 1; # The 3 variables in the new subrountine, 'normalline', 'actionline' and # 'thirdline' represents regular expressions for extracting information from # the logfile. normalline is for lines where the person merely said # something, actionline is for lines where the person performed an action, # and thirdline matches everything else, including things like kicks, nick # changes, and op grants. See the thirdline subroutine for a list of # everything it should match. sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '', actionline => '', thirdline => '', }; bless($self, $type); return $self; } # Parse a normal line - returns a hash with 'hour', 'nick' and 'saying' sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } # Parse an action line - returns a hash with 'hour', 'nick' and 'saying' sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { # Most log formats are regular enough that you can just match the # appropriate things with parentheses in the regular expression. $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } # Parses the 'third' line - (the third line is everything else, like # topic changes, mode changes, kicks, etc.) # thirdline() has to return a hash with the following keys, for # every format: # hour - the hour we're in (for timestamp logging) # min - the minute we're in (for timestamp logging) # nick - the nick # kicker - the nick which kicked somebody (if any) # newtopic - the new topic (if any) # newmode - deops or ops, must be '+o' or '-o', or '+ooo' # newjoin - a new nick which has joined the channel # newnick - a person has changed nick and this is the new nick # # It should return a hash with the following (for formatting lines in html) # # kicktext - the kick reason (if any) # modechanges - data of the mode change ('Nick' in '+o Nick') # # The hash may also have a "repeated" key indicating the number of times # the line was repeated. (Used by eggdrops log for example.) sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; # Format-specific stuff goes here. return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/ircle.pm0000774000076400007650000000320011705647720017542 0ustar wadewadepackage Pisg::Parser::Format::ircle; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+):\d+ \w+:[^\w]+(\w+): (.*)', actionline => '^(\d+):\d+ \w+:[^\w]+(\w+) (.*)', thirdline => '^(\d+):(\d+) \w+: \*\*\* (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($5.$6) eq 'beenkicked') { $hash{kicker} = $11; } elsif ($3 eq 'Topic') { $hash{newtopic} = "$6 $7 $8"; } elsif (($3.$4) eq 'Modechange') { $hash{newmode} = substr($5, 1); } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $3; } elsif (($5.$6) eq 'nowknown') { $hash{newnick} = $8; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/winbot.pm0000774000076400007650000000450011705647720017752 0ustar wadewadepackage Pisg::Parser::Format::winbot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d\d):\d\d\.\d\d \d+\/\d+\/\d+ <([^\/]+)\/([^\>]+)> (.*)', actionline => '^(\d\d):\d\d\.\d\d \d+\/\d+\/\d+ \* ([^\/]+)\/(\S+) (.*)', thirdline => '^(\d\d):(\d\d)\.\d\d \d+\/\d+\/\d+ \*{3}\s(.+)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } return; } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o && lc($3) eq lc($self->{cfg}->{channel})) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $4; return \%hash; } return; } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if ($3 =~ /^(\S+) was kicked from (\S+) by (\S+) .+/) { if (lc($2) eq lc($self->{cfg}->{channel})) { $hash{nick} = $1; $hash{kicker} = $3; } } elsif ($3 =~ /^([^\/]+)\/(\S+) changes topic to \"(.+)\"[^\"]*$/) { if (lc($2) eq lc($self->{cfg}->{channel})) { $hash{nick} = $1; $hash{newtopic} = $3; } } elsif ($3 =~ /^([^\/]+)\/(\S+) sets mode: (\S+) [^\)]+/) { if (lc($2) eq lc($self->{cfg}->{channel})) { $hash{nick} = $1; $hash{newmode} = $3; } } elsif ($3 =~ /^(\S+) has joined (\S+)/) { if (lc($2) eq lc($self->{cfg}->{channel})) { $hash{nick} = $1; $hash{newjoin} = $1; } } elsif ($3 =~ /^(\S+) is now known as (\S+)/) { $hash{nick} = $1; $hash{newnick} = $2; } elsif ($3 =~ /^(\S+) /) { $hash{nick} = $1; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/hydra.pm0000774000076400007650000000363711705647720017571 0ustar wadewadepackage Pisg::Parser::Format::hydra; use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[\d+-\d+-\d+ (\d+):\d+:\d+\] <([^>\s]+)> (.*)', actionline => '^\[\d+-\d+-\d+ (\d+):\d+:\d+\] \* (\S+) (.+)', thirdline => '^\[\d+-\d+-\d+ (\d+):(\d+):\d+\] \*{3} (.+)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; # Format-specific stuff goes here. if ($3 =~ /^(\S+) was kicked from (\S+) by (\S+) (.+)/) { $hash{nick} = $1; $hash{kicker} = $3; $hash{kicktext} = $4; } elsif ($3 =~ /^(\S+) changed topic to (.+)/) { $hash{nick} = $1; $hash{newtopic} = $2; } elsif ($3 =~ /^(\S+) sets channel \S+ mode (\S+) (.+)/) { $hash{nick} = $1; $hash{newmode} = $2; $hash{modechanges} = $3; } elsif ($3 =~ /^(\S+) \S+ has joined channel \S+/) { $hash{nick} = $1; $hash{newjoin} = $1; } elsif ($3 =~ /^(\S+) changed nick to (\S+)/) { $hash{nick} = $1; $hash{newnick} = $2; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/miau.pm0000774000076400007650000000455611705647720017416 0ustar wadewadepackage Pisg::Parser::Format::miau; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # This Parser works with miau version 0.5.3, your milage may vary. # 2005-05-07 Kresten Kjeldgaard # This is a version of the muh2 parser that supports the log file format of the # miau bouncer, mostly topic changes that are handled differently. # 2006-10-26 adapted to miau logfile-format 0.6.x by mnh, jha and Myon use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^[a-zA-Z]{3} \d{1,2} (\d+):\d+\S+ <([^>]+)> (.*)$', actionline => '^[a-zA-Z]{3} \d{1,2} (\d+):\d+\S+ \* (\S+) (.*)$', thirdline => '^[a-zA-Z]{3} \d{1,2} (\d+):(\d+)\S+ [\-><\*][\-\*]{2} (.+)$' }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { my @line = split(/\s/, $3); $hash{hour} = $1; $hash{min} = $2; ($hash{nick} = $line[0]) =~ s/^[@%\+]//o; # Remove prefix if ($#line >= 4 && ($line[1].$line[2]) eq 'waskicked') { $hash{kicker} = $line[4]; } elsif ($#line >= 6 && (($line[1].$line[2]) eq 'haschanged')) { $hash{newtopic} = join(' ', @line[6..$#line]); $hash{newtopic} =~ s/^'//; $hash{newtopic} =~ s/'$//; } elsif ($#line >= 3 && ($line[1].$line[2]) eq 'setsmode') { $hash{newmode} = $line[3]; } elsif ($#line >= 3 && ($line[2].$line[3]) eq 'hasjoined') { $hash{newjoin} = $line[0]; } elsif ($#line >= 5 && ($line[2].$line[3]) eq 'nowknown') { $hash{newnick} = $line[5]; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/eggdrop.pm0000774000076400007650000000443211705647720020103 0ustar wadewadepackage Pisg::Parser::Format::eggdrop; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[(\d+):\d+(?:\:\d+)?\] <([^>]+)> (.*)$', actionline => '^\[(\d+):\d+(?:\:\d+)?\] Action: (\S+) (.*)$', thirdline => '^\[(\d+):(\d+)(?:\:\d+)?\] (\S+) (\S+) (\S+) (\S+)(.*)$', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'kickedfrom') { $7 =~ /^ by ([\S]+):\s*(.*)/; $hash{kicktext} = $2; $1 =~ /([^!]+)/; # Remove anything after the ! $hash{kicker} = $1; } elsif ($3 eq 'Topic') { $7 =~ /^ by (\S*)!(\S+): (.*)/; $hash{nick} = $1 || $2; # $1 might be empty if topic is reset by server $hash{newtopic} = $3; } elsif (($4.$5) eq 'modechange') { my $newmode = $6; if ($7 =~ /^ (.+) by ([\S]+)!.*/) { $hash{modechanges} = $2; $hash{nick} = $2; $newmode =~ s/^\'//; $hash{newmode} = $newmode; } } elsif ($5 eq 'joined') { $hash{newjoin} = $3; } elsif (($3.$4) eq 'Nickchange:') { $hash{nick} = $5; $7 =~ /([\S]+)/; $hash{newnick} = $1; } elsif (($3.$4.$5) eq 'Lastmessagerepeated') { $hash{repeated} = $6; } $hash{nick} =~ /([^!]+)/; $hash{nick} = $1; return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/weechat3.pm0000774000076400007650000000367111705647720020163 0ustar wadewadepackage Pisg::Parser::Format::weechat3; # Documentation for the Pisg::Parser::Format modules is found in Template.pm use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\d+-\d+-\d+ (\d+):\d+:\d+\t[@%+~&]?([^ <-]\S+)\t(.*)', actionline => '^\d+-\d+-\d+ (\d+):\d+:\d+\t \*\t(\S+) (.*)', thirdline => '^\d+-\d+-\d+ (\d+):(\d+):\d+\t(?:--|<--|-->)\t(\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'haskicked') { $hash{nick} = $6; $hash{kicker} = $3; } elsif ($4.$5.$6 eq 'haschangedtopic') { $hash{newtopic} = $8; $hash{newtopic} =~ m/" to "(.*)"/; $hash{newtopic} = $1; } elsif ($3 eq 'Mode') { $hash{newmode} = substr($5, 1); $hash{nick} = $8 || $7; $hash{nick} =~ s/.* (\S+)$/$1/; # Get the last word of the string } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $3; } elsif (($5.$6) eq 'nowknown') { if ($8 =~ /^\s+(\S+)/) { $hash{newnick} = $1; } } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/infobot.pm0000774000076400007650000000477511705647720020126 0ustar wadewadepackage Pisg::Parser::Format::infobot; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # Note that infobot log files do not distinguish between action lines and # normal lines. use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+) \[\d+\] <([^\/]+)\/[^>]+> (.*)', actionline => '^NA', thirdline => '^(\d+) \[\d+\] >>> (.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; my $sec; my $min; my $hour; my $mday; my $mon; my $year; my $wday; my $yday; my $isdst; if ($line =~ /$self->{normalline}/o) { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($1); $hash{hour} = $hour; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; my $sec; my $min; my $hour; my $mday; my $mon; my $year; my $wday; my $yday; my $isdst; if ($line =~ /$self->{actionline}/o) { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($1); $hash{hour} = $hour; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; my $sec; my $min; my $hour; my $mday; my $mon; my $year; my $wday; my $yday; my $isdst; if ($line =~ /$self->{thirdline}/o) { ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($1); $hash{hour} = $hour; $hash{min} = $min; if ($2 =~ /^\[1m([^(\[0m)]*)\[0m was kicked off \[1m[^\[]*\[0m by \[1m([^(\[0m)]*)\[0m .*/) { $hash{nick} = $1; $hash{kicker} = $2; } elsif ($2 =~ /^([^(\[1m)]*)\[1m\[\[0m#[^\[ ]+( ?:?)(.*)\[1m\]\[0m set the topic: (.*)/) { $hash{nick} = $1; $hash{newtopic} = "$3$2$4"; } elsif ($2 =~ /^mode\/\S* \[\[1m([\+\-]o+) .* by \[1m(\S*)\[0m/) { $hash{newmode} = $1; $hash{nick} = $2; } elsif ($2 =~ /^(\S*) \(\S*\) has joined \#\S*/) { $hash{newjoin} = $1; } elsif ($2 =~ /^\[1;32m([^(\[0m)]*)\[0m materializes into \[1;32m([^(\[0m)]*)\[0m/) { $hash{nick} = $1; $hash{newnick} = $2; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/virc98.pm0000774000076400007650000000412611705647720017600 0ustar wadewadepackage Pisg::Parser::Format::virc98; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # Parser for MeGALiTH's Visual IRC 98 on IRCnet (nicks lenght 9 chars) # by HceZar hcezar@freemail.it # Fender @ IRCnet #oristano,#italymania use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^(\d+)\.\d+[^ ]+ [<\[](.{1,9})[\]>]\s+(.*)', actionline => '^(\d+)\.\d+[^ ]+ \* (\S+) (.*)', thirdline => '^(\d+)\.(\d+)[^ ]+.* \*\*\* (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S+)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; ($hash{nick} = $2) =~ s/^[@%\+~&]//o; # Remove prefix $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; if (($4.$5) eq 'haskicked') { $hash{kicker} = $3; $hash{nick} = $6; } elsif ($4.$5.$6.$7 eq 'haschangedthetopic') { $hash{nick} = $3; $hash{newtopic} = "$11"; } elsif (($3.$4) eq 'Modechange') { $hash{newmode} = remove_braces($5); $hash{nick} = $11; } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $3; $hash{nick} = $3; } elsif (($5.$6) eq 'nowknown') { $hash{newnick} = $8; $hash{nick} = $3; } return \%hash; } else { return; } } sub remove_braces { my $str = shift; $str =~ s/^\[//; return $str; } 1; pisg-0.73/modules/Pisg/Parser/Format/xchat.pm0000774000076400007650000000465111705647720017566 0ustar wadewadepackage Pisg::Parser::Format::xchat; # Documentation for the Pisg::Parser::Format modules is found in Template.pm # This module supports both the old and new logformat (after 1.8.7) use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '(\d+):\d+:\d+ <[@%+~&]?([^>\s]+)>\s+(.*)', actionline => '(\d+):\d+:\d+ \*{1,}\s+(\S+) (.*)', thirdline => '(\d+):(\d+):\d+ [<-]-[->]\s+(\S+) (\S+) (\S+) (\S+) ((\S+)\s*(\S+)?\s*(.*)?)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; if (($4.$5) eq 'haskicked') { $hash{kicker} = $3; $hash{nick} = $6; } elsif (($4.$5) eq 'haschanged') { $hash{newtopic} = $10; } elsif (($4.$5.$6) eq 'giveschanneloperator') { $hash{newmode} = '+o'; } elsif (($4.$5.$6) eq 'removeschanneloperator') { $hash{newmode} = '-o'; } elsif (($4.$5.$6) eq 'giveschannelhalf-operator') { $hash{newmode} = '+h'; } elsif (($4.$5.$6) eq 'removeschannelhalf-operator') { $hash{newmode} = '-h'; } elsif (($4.$5) eq 'givesvoice') { $hash{newmode} = '+v'; } elsif (($4.$5) eq 'removesvoice') { $hash{newmode} = '-v'; } elsif (($5.$6) eq 'hasjoined') { $hash{newjoin} = $1; } elsif (($5.$6) eq 'nowknown') { $hash{newnick} = $9; } elsif (($3.$4.$6) eq 'Topicforis') { $self->{topictemp} = $7; $hash{newtopic} = $7; } elsif (($3.$4.$6) eq 'Topicforset') { $hash{nick} = $9; $hash{newtopic} = $self->{topictemp}; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Format/muh.pm0000774000076400007650000000506011705647720017243 0ustar wadewadepackage Pisg::Parser::Format::muh; # This is a Parser vor the well-known "muh-bouncer" # by Bastian Friedrichs and Sebastian Erlhofer # parser@boitl.org use strict; $^W = 1; sub new { my ($type, %args) = @_; my $self = { cfg => $args{cfg}, normalline => '^\[\w\w\w \d\d \w\w\w (\d+):\d+:\d+\] <([^>\s]+)>\s+(.*)', actionline => '^\[\w\w\w \d\d \w\w\w (\d+):\d+:\d+\] <([^>\s]+)>\sACTION\s+(.*)', #thirdline => '^\[\w\w\w \d\d \w\w\w (\d+):(\d+):\d+\] \*\*\*\s+(\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (.*)', thirdline => '^\[\w\w\w \d\d \w\w\w (\d+):(\d+):\d+\] \*\*\*\s+(\S+) (\S+) (\S+) (\S+) (\S+) (\S+) (\S*)(.*)', }; bless($self, $type); return $self; } sub normalline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{normalline}/o and !($line =~ /$/)) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub actionline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{actionline}/o) { $hash{hour} = $1; $hash{nick} = $2; $hash{saying} = $3; return \%hash; } else { return; } } sub thirdline { my ($self, $line, $lines) = @_; my %hash; if ($line =~ /$self->{thirdline}/o) { $hash{hour} = $1; $hash{min} = $2; $hash{nick} = $3; # Format-specific stuff goes here. if (($3.$6) eq 'Kickby') { $hash{kicker} = $7; $hash{nick} = $5; } elsif (($3.$4) eq 'Topicchange') { $hash{newtopic} = $10; #$hash{newtopic} = $9.$10; #$hash{newtopic} =~ s/^.* \):(.*)/$9$10/; $hash{nick} = $8; } elsif ($3 eq 'Mode') { my $nm; $nm = substr($5, 1); if (($nm eq "+o") || ($nm eq "-o")) { $hash{nick} = $8; $hash{newmode} = $nm; } elsif (($nm eq "+oo") || ($nm eq "-oo")) { $hash{nick} = $9; $hash{newmode} = $nm; } elsif (($nm eq "+ooo") || ($nm eq "-ooo")) { $hash{nick} = substr($10, 1, index($10, ' ', 1)-1); $hash{newmode} = $nm; } } elsif (($2.$3) eq '\*\*\*Join') { $hash{newjoin} = $5; } return \%hash; } else { return; } } 1; pisg-0.73/modules/Pisg/Parser/Logfile.pm0000774000076400007650000010154511705647720016610 0ustar wadewadepackage Pisg::Parser::Logfile; # Copyright and license, as well as documentation(POD) for this module is # found at the end of the file. use strict; $^W = 1; # the log cache use Data::Dumper; $Data::Dumper::Indent = 1; my $cache; # test for Text::Iconv my $have_iconv = 1; eval 'use Text::Iconv'; $have_iconv = 0 if $@; sub new { my $type = shift; my $self = shift; # get cfg and users # Import common functions in Pisg::Common require Pisg::Common; Pisg::Common->import(); bless($self, $type); # Pick our parser. $self->{parser} = $self->_choose_format($self->{cfg}->{format}); if($self->{cfg}->{logcharsetfallback} and not $self->{cfg}->{logcharset}) { print "LogCharset undefined, assuming LogCharset = LogCharsetFallback\n" unless ($self->{cfg}->{silent}); $self->{cfg}->{logcharset} = $self->{cfg}->{logcharsetfallback}; } if($self->{cfg}->{logcharset}) { if($have_iconv) { # use converter if charsets differ or there is a fallback charset # (in the latter case the converter is also used to test if the # line is in the proper charset) if(($self->{cfg}->{logcharset} ne $self->{cfg}->{charset}) or $self->{cfg}->{logcharsetfallback}) { $self->{iconv} = Text::Iconv->new($self->{cfg}->{logcharset}, $self->{cfg}->{charset}); } if($self->{cfg}->{logcharsetfallback}) { $self->{iconvfallback} = Text::Iconv->new($self->{cfg}->{logcharsetfallback}, $self->{cfg}->{charset}); } } else { print "Text::Iconv is not installed, skipping charset conversion of logfiles\n" unless ($self->{cfg}->{silent}); } } # precompile the regexps used (we can't use /o since the config might be different per channel) $self->{foulwords_regexp} = qr/($self->{cfg}->{foulwords})/i if $self->{cfg}->{foulwords}; $self->{ignorewords_regexp} = qr/$self->{cfg}->{ignorewords}/i if $self->{cfg}->{ignorewords}; $self->{violentwords_regexp} = qr/^($self->{cfg}->{violentwords}) (\S+)(.*)/i if $self->{cfg}->{violentwords}; $self->{chartsregexp} = qr/^$self->{cfg}->{chartsregexp}/i if $self->{cfg}->{chartsregexp}; return $self; } # The function to choose which module to use. sub _choose_format { my $self = shift; my $format = shift; $self->{parser} = undef; eval <<_END; use lib '$self->{cfg}->{modules_dir}'; use Pisg::Parser::Format::$format; \$self->{parser} = new Pisg::Parser::Format::$format( cfg => \$self->{cfg}, ); _END if ($@) { print STDERR "Could not load parser for '$format': $@\n"; return undef; } return $self->{parser}; } sub analyze { my $self = shift; unless (defined $self->{parser}) { print STDERR "Skipping channel '$self->{cfg}->{channel}' due to lack of parser.\n"; return undef } my $starttime = time(); my @logfiles = @{$self->{cfg}->{logfile}}; # expand wildcards @logfiles = map { if(/[\[*?]/) { glob; } else { $_; } } @logfiles; foreach my $logdir (@{$self->{cfg}->{logdir}}) { push @logfiles, $self->_parse_dir($logdir); # get all files in dir } my $count = @logfiles; my $shift = 0; if($self->{cfg}->{nfiles} > 0) { # chop list to maximal length $shift = @logfiles - $self->{cfg}->{nfiles}; splice(@logfiles, 0, $shift) if $shift > 0; } unless ($self->{cfg}->{silent}) { my $msg = ""; $msg = ", parsing the last $self->{cfg}->{nfiles}" if ($shift > 0); print "$count logfile(s) found$msg, using $self->{cfg}->{format} format...\n\n" } my (%stats, %lines); %stats = ( oldtime => 24, days => 0, lastnick => '', monocount => 0, day_lines => [ undef ], day_times => [ undef ], parsedlines => 0, totallines => 0, ); if ($self->{cfg}->{cachedir} and not -d $self->{cfg}->{cachedir}) { print STDERR "CacheDir \"$self->{cfg}->{cachedir}\" not found. Skipping caching.\n"; delete $self->{cfg}->{cachedir}; } foreach my $logfile (@logfiles) { # Run through the logfile print "Analyzing log $logfile... " unless ($self->{cfg}->{silent}); my $s = { oldtime => 24, days => 0, firsttime => 0, lastnick => '', parsedlines => 0, totallines => 0, }; my $l = {}; if ($self->{cfg}->{cachedir} and $self->_read_cache(\$s, \$l, $logfile)) { # take care of false nicks/words, this only happens with cache foreach (keys %{$s->{lastvisited}}) { find_alias($_); } } else { $self->_parse_file($s, $l, $logfile); if ($self->{cfg}->{cachedir}) { $self->_update_cache($s, $l, $logfile); } } $self->_merge_stats(\%stats, $s); # merge per-file stats into global stats $self->_merge_lines(\%lines, $l); print "$stats{days} days, $stats{parsedlines} lines total\n" unless ($self->{cfg}->{silent}); } if ($self->{cfg}->{statsdump}) { open C, "> $self->{cfg}->{statsdump}" or die "$self->{cfg}->{statsdump}: $!"; print C Data::Dumper->Dump([\%stats, \%lines], ["stats", "lines"]); close C; } $self->_pick_random_lines(\%stats, \%lines); _uniquify_nicks(\%stats); my ($sec,$min,$hour) = gmtime(time() - $starttime); my $processtime = sprintf('%02d hours, %02d minutes and %02d seconds', $hour, $min, $sec); $stats{processtime}{hours} = sprintf('%02d', $hour); $stats{processtime}{mins} = sprintf('%02d', $min); $stats{processtime}{secs} = sprintf('%02d', $sec); print "Channel analyzed successfully in $processtime on ", scalar localtime(time()), "\n\n" unless ($self->{cfg}->{silent}); return \%stats; } sub _parse_dir { my $self = shift; my $logdir = shift; # Add trailing slash when it's not there.. $logdir =~ s/([^\/])$/$1\//; unless ($self->{cfg}->{silent}) { print "Looking for logfiles in $logdir...\n\n" } my @filesarray; opendir(LOGDIR, $logdir) or die("Can't opendir ${logdir}: $!"); unless(@filesarray = grep { /^[^\.]/ && /^$self->{cfg}->{logprefix}/ && -f "$logdir/$_" } readdir(LOGDIR)) { print ("No files in \"$logdir\" matched prefix \"$self->{cfg}->{logprefix}\"\n"); return; } closedir(LOGDIR); if ($self->{cfg}->{logsuffix} ne '') { my @temparray; my %months = ( 'jan' => '0', 'feb' => '1', 'mar' => '2', 'apr' => '3', 'may' => '4', 'jun' => '5', 'jul' => '6', 'aug' => '7', 'sep' => '8', 'oct' => '9', 'nov' => '10', 'dec' => '11', ); my ($mreg, $dreg, $yreg) = split(/\|\|/, $self->{cfg}->{logsuffix}); my (@month, @day, @year); for my $file (@filesarray) { LOOPSTART: if ($file =~ /$mreg/) { my $month = $1; $month = lc $month; $month = $months{$month} if (defined $months{$month}); push @month, $month; } else { splice(@filesarray,$#month + 1, 1); if ($file = $filesarray[$#month + 1]) { goto LOOPSTART; } else { last; } } if ($file =~ /$dreg/) { push @day, $1; } else { splice(@filesarray,$#day + 1, 1); splice(@month,$#day + 1); if ($file = $filesarray[$#day + 1]) { goto LOOPSTART; } else { last; } } if ($file =~ /$yreg/) { push @year, $1; } else { splice(@filesarray,$#year + 1, 1); splice(@month,$#year + 1); splice(@day,$#year + 1); if ($file = $filesarray[$#year + 1]) { goto LOOPSTART; } else { last; } } } @filesarray = @filesarray[ sort { $year[$a] <=> $year[$b] || $month[$a] <=> $month[$b] || $day[$a] <=> $day[$b] } 0..$#filesarray ]; } else { @filesarray = sort {lc($a) cmp lc($b)} @filesarray; } return map { "$logdir$_" } @filesarray; } # This parses the file... sub _parse_file { my $self = shift; my ($stats, $lines, $file) = @_; if ($file =~ /.bz2?$/ && -f $file) { open (LOGFILE, "bunzip2 -c $file |") or die("$0: Unable to open logfile($file): $!\n"); } elsif ($file =~ /.gz$/ && -f $file) { open (LOGFILE, "gunzip -c $file |") or die("$0: Unable to open logfile($file): $!\n"); } else { open (LOGFILE, $file) or die("$0: Unable to open logfile($file): $!\n"); } while(my $line = ) { $line = _strip_mirccodes($line); $line =~ s/\r+$//; # Strip DOS Formatting if($self->{iconv}) { # iconv is defined only if LogCharset is set my $line2 = $self->{iconv}->convert($line); if(not $line2 and $self->{iconvfallback}) { $line2 = $self->{iconvfallback}->convert($line); } if($line2) { $line = $line2; } else { print "Charset conversion failed for '$line'\n" unless ($self->{cfg}->{silent}); } } my $hashref; # Match normal lines. if ($hashref = $self->{parser}->normalline($line, $.)) { my $repeated = 0; if (defined $hashref->{repeated}) { $repeated = $hashref->{repeated}; } my ($hour, $nick, $saying, $i); for ($i = 0; $i <= $repeated; $i++) { if ($i > 0) { $hashref = $self->{parser}->normalline($stats->{lastnormal}, $.); #Increment number of lines for repeated lines } $hour = $self->_adjusttimeoffset($hashref->{hour}); $nick = find_alias($hashref->{nick}); checkname($hashref->{nick}, $nick, $stats) if ($self->{cfg}->{showmostnicks}); $saying = $hashref->{saying}; if ($hour < $stats->{oldtime}) { $stats->{firsttime} = $hour if $stats->{oldtime} == 24; # save stamp for merging $stats->{days}++; @{$stats->{day_times}[$stats->{days}]} = (0, 0, 0, 0); $stats->{day_lines}->[$stats->{days}] = 0; } $stats->{oldtime} = $hour; if (!is_ignored($nick)) { $stats->{parsedlines}++; # Timestamp collecting $stats->{times}{$hour}++; $stats->{day_times}[$stats->{days}][int($hour/6)]++; $stats->{day_lines}->[$stats->{days}]++; $stats->{lines}{$nick}++; $stats->{lastvisited}{$nick} = $stats->{days}; $stats->{line_times}{$nick}[int($hour/6)]++; # Count up monologues if ($stats->{lastnick} eq $nick) { $stats->{monocount}++; if ($stats->{monocount} == 5) { $stats->{monologues}{$nick}++; } } else { $stats->{monocount} = 0; } $stats->{lastnick} = $nick; my $len = length($saying); if ($len > $self->{cfg}->{minquote} && $len < $self->{cfg}->{maxquote}) { push @{ $lines->{sayings}{$nick} }, $saying; } elsif (!$lines->{sayings}{$nick}) { # Just fill the users first saying in if he hasn't # said anything yet, to get rid of empty quotes. push @{ $lines->{sayings}{$nick} }, substr($saying, 0, $self->{cfg}->{maxquote}); } $stats->{lengths}{$nick} += $len; $stats->{questions}{$nick}++ if (index($saying, '?') > -1); $stats->{shouts}{$nick}++ if (index($saying, '!') > -1); if ($saying !~ /[a-z]/o && $saying =~ /[A-Z]/o) { # Ignore single smileys on a line. eg. ' :P' if ($saying !~ /^[8;:=][ ^-o]?[)pPD\}\]>]$/o) { $stats->{allcaps}{$nick}++; push @{ $lines->{allcaplines}{$nick} }, $line; } } if ($self->{foulwords_regexp} and my @foul = $saying =~ /$self->{foulwords_regexp}/) { $stats->{foul}{$nick} += scalar @foul; push @{ $lines->{foullines}{$nick} }, $line; } # Who smiles the most? my $e = '[8;:=%]'; # eyes my $n = '[-oc*^]'; # nose # smileys including asian-style (^^ ^_^' ^^; \o/) if ($saying =~ /(>?$e'?$n[\)pPD\}\]>]|[\(\{\[<]$n'?$e]|\([;:]|\^[_o-]*\^[';]|\\[o.]\/)/o) { $stats->{smiles}{$nick}++; $stats->{smileys}{$1}++; $stats->{smileynicks}{$1} = $nick; } # asian frown: ;_; if ($saying =~ /($e'?$n[\(\[\\\/\{|]|[\)\]\\\/\}|]$n'?$e|[;:][\(\/]|[\)D]:|;_+;|T_+T|-[._]+-)/o and $saying !~ /\w+:\/\//o) { $stats->{frowns}{$nick}++; $stats->{smileys}{$1}++; $stats->{smileynicks}{$1} = $nick; } # require 2 chars (catches C++), nick must not end in [+=-] if ($saying =~ /^(\S+[^\s+=-])(\+\+|==|--)$/) { my $thing = lc $1; my $k = $2 eq "++" ? 1 : ($2 eq "==" ? 0 : -1); $stats->{karma}{$thing}{$nick} = $k if $thing =~ /\w\W*?\w/ and !is_ignored($thing) and $thing ne lc($nick); } # Find URLs if (my @urls = match_urls($saying)) { foreach my $url (@urls) { if(!url_is_ignored($url)) { $stats->{urlcounts}{$url}++; $stats->{urlnicks}{$url} = $nick; } } } if ($saying =~ /$self->{chartsregexp}/i) { $self->_charts($stats, $1, $nick); } if (my $s = $self->{users}->{sex}{$nick}) { $stats->{sex_lines}{$s}++; $stats->{sex_line_times}{$s}[int($hour/6)]++; } _parse_words($stats, $saying, $nick, $self->{ignorewords_regexp}, $hour); } # ignored } # repeated $stats->{lastnormal} = $line; $repeated = 0; } # normal lines # Match action lines. elsif ($hashref = $self->{parser}->actionline($line, $.)) { $stats->{parsedlines}++; my ($hour, $nick, $saying); $hour = $self->_adjusttimeoffset($hashref->{hour}); $nick = find_alias($hashref->{nick}); checkname($hashref->{nick}, $nick, $stats) if ($self->{cfg}->{showmostnicks}); $saying = $hashref->{saying}; if ($hour < $stats->{oldtime}) { $stats->{firsttime} = $hour if $stats->{oldtime} == 24; # save stamp for merging $stats->{days}++; @{$stats->{day_times}[$stats->{days}]} = (0, 0, 0, 0); $stats->{day_lines}->[$stats->{days}] = 0; } $stats->{oldtime} = $hour; if (!is_ignored($nick)) { # Timestamp collecting $stats->{times}{$hour}++; $stats->{day_times}[$stats->{days}][int($hour/6)]++; $stats->{day_lines}->[$stats->{days}]++; $stats->{actions}{$nick}++; push @{ $lines->{actionlines}{$nick} }, $line; $stats->{lines}{$nick}++; $stats->{lastvisited}{$nick} = $stats->{days}; $stats->{line_times}{$nick}[int($hour/6)]++; if ($self->{violentwords_regexp} and $saying =~ /$self->{violentwords_regexp}/) { my $victim; unless ($victim = is_nick($2)) { foreach my $trynick (split(/\s+/, $3)) { last if ($victim = is_nick($trynick)); } unless ($victim) { $victim = $2; } } if (!is_ignored($victim)) { $stats->{violence}{$nick}++; $stats->{attacked}{$victim}++; push @{ $lines->{violencelines}{$nick} }, $line; push @{ $lines->{attackedlines}{$victim} }, $line; } } if ($saying =~ /$self->{chartsregexp}/i) { $self->_charts($stats, $1, $nick); } $stats->{lengths}{$nick} += length($saying); if (my $s = $self->{users}->{sex}{$nick}) { $stats->{sex_lines}{$s}++; $stats->{sex_line_times}{$s}[int($hour/6)]++; } _parse_words($stats, $saying, $nick, $self->{ignorewords_regexp}, $hour); } # ignored } # action lines # Match *** lines. elsif (($hashref = $self->{parser}->thirdline($line, $.)) and $hashref->{nick}) { $stats->{parsedlines}++; my ($hour, $min, $nick, $kicker, $newtopic, $newmode, $newjoin); my ($newnick); $hour = $self->_adjusttimeoffset($hashref->{hour}); $min = $hashref->{min}; $nick = find_alias($hashref->{nick}); checkname($hashref->{nick}, $nick, $stats) if ($self->{cfg}->{showmostnicks}); $kicker = find_alias($hashref->{kicker}) if ($hashref->{kicker}); $newtopic = $hashref->{newtopic}; $newmode = $hashref->{newmode}; $newjoin = $hashref->{newjoin}; $newnick = $hashref->{newnick}; if ($hour < $stats->{oldtime}) { $stats->{firsttime} = $hour if $stats->{oldtime} == 24; # save stamp for merging $stats->{days}++; @{$stats->{day_times}[$stats->{days}]} = (0, 0, 0, 0); $stats->{day_lines}->[$stats->{days}] = 0; } $stats->{oldtime} = $hour; if (!is_ignored($nick)) { # Timestamp collecting $stats->{times}{$hour}++; $stats->{day_times}[$stats->{days}][int($hour/6)]++; $stats->{day_lines}->[$stats->{days}]++; $stats->{lastvisited}{$nick} = $stats->{days}; if (defined($kicker)) { if (!is_ignored($kicker)) { $stats->{kicked}{$kicker}++; $stats->{gotkicked}{$nick}++; push @{ $lines->{kicklines}{$nick} }, $line; } } elsif (defined($newtopic) && $newtopic ne '') { push @{$stats->{topics}}, { topic => $newtopic, nick => $nick, hour => $hour, min => $min, days => $stats->{days}, }; } elsif (defined($newmode)) { _modechanges($stats, $newmode, $nick); } elsif (defined($newjoin)) { $stats->{joins}{$nick}++; } elsif (defined($newnick) and ($self->{cfg}->{nicktracking} == 1)) { # Resolve new nick to the correct alias (this will create a hard-alias if it is using a regex) $newnick = find_alias($newnick); add_alias($nick, $newnick); checkname($nick, $newnick, $stats) if ($self->{cfg}->{showmostnicks}); } } } # *** lines unless ($stats->{parsedlines} % 10000) { # keep only recent quotes to save memory $self->_trim_lines($lines); } } # while(my $line = ) $self->_trim_lines($lines); my $wordcount = sqrt(sqrt(keys %{$stats->{wordcounts}})); # remove less frequent words foreach my $word (keys %{$stats->{wordcounts}}) { if ($stats->{wordcounts}->{$word} < $wordcount) { next if defined $stats->{chartcounts}{$word}; delete $stats->{wordcounts}->{$word}; delete $stats->{wordnicks}->{$word}; delete $stats->{word_upcase}->{$word}; } } $stats->{totallines} = $.; close(LOGFILE); } sub _modechanges { my $stats = shift; my $newmode = shift; my $nick = shift; my (@voice, @halfops, @ops, $plus); foreach (split(//, $newmode)) { if ($_ eq 'o') { $ops[$plus]++; } elsif ($_ eq 'h') { $halfops[$plus]++; } elsif ($_ eq 'v') { $voice[$plus]++; } elsif ($_ eq '+') { $plus = 0; } elsif ($_ eq '-') { $plus = 1; } } $stats->{gaveops}{$nick} += $ops[0] if $ops[0]; $stats->{tookops}{$nick} += $ops[1] if $ops[1]; $stats->{gavehalfops}{$nick} += $halfops[0] if $halfops[0]; $stats->{tookhalfops}{$nick} += $halfops[1] if $halfops[1]; $stats->{gavevoice}{$nick} += $voice[0] if $voice[0]; $stats->{tookvoice}{$nick} += $voice[1] if $voice[1]; } sub _parse_words { my ($stats, $saying, $nick, $ignorewords_regexp, $hour) = @_; # Cache time of day my $tod = int($hour/6); foreach my $word (split(/[\s,!?.:;)(\"]+/o, $saying)) { # ignore if $word is empty next if $word eq ""; $stats->{words}{$nick}++; $stats->{word_times}{$nick}[$tod]++; # remove uninteresting words next if $ignorewords_regexp and $word =~ m/$ignorewords_regexp/i; # ignore contractions next if ($word =~ m/'.{1,2}$/o); # Also ignore stuff from URLs. next if ($word =~ m/^https?$|^\/\//o); my $lcword = lc $word; $stats->{wordcounts}{$lcword}++; $stats->{wordnicks}{$lcword} = $nick; $stats->{word_upcase}{$lcword} ||= $word; # remember first-seen case } } sub _charts { my ($self, $stats, $Song, $nick) = @_; unless (defined $Song) { warn "Your ChartsRegexp is b0rked. Read the manual! This happened"; return; } $Song =~ s/_/ /g; $Song =~ s/\d+ ?- ?//; $Song =~ s/\.(mp3|ogg|wma)//ig; $Song =~ s/\[[^\] ]*\]/ /g; # strip stuff in brackets [44kbps] $Song =~ s/^ *[^\w]* *| *[^\w]* *$//g; return unless length $Song; my $song = lc $Song; $stats->{word_upcase}{$song} = $Song; $stats->{chartcounts}{$song}++; $stats->{chartnicks}{$song} = $nick; } sub _trim_lines { my ($self, $lines) = @_; foreach my $n (keys %{$lines->{sayings}}) { my $x = @{$lines->{sayings}->{$n}}; splice(@{$lines->{sayings}->{$n}}, 0, ($x - 15)) if ($x > 30); } foreach my $n (keys %{$lines->{actionlines}}) { my $x = @{$lines->{actionlines}->{$n}}; splice(@{$lines->{actionlines}->{$n}}, 0, ($x - 15)) if ($x > 30); } } sub _pick_random_lines { my ($self, $stats, $lines) = @_; foreach my $key (keys %{ $lines }) { foreach my $nick (keys %{ $lines->{$key} }) { $stats->{$key}{$nick} = $self->_random_line($lines, $key, $nick); } } } sub _random_line { my ($self, $lines, $key, $nick) = @_; my $count = 0; my ($random, $out, $out2) = ("", "", ""); #warn "$nick did not say anything" unless @{ $lines->{$key}{$nick} }; while (++$count < 20) { $random = ${ $lines->{$key}{$nick} }[rand @{ $lines->{$key}{$nick} }]; if (length($random) < $self->{cfg}->{minquote} or length($random) > $self->{cfg}->{maxquote}) { $out2 = $random; # 2nd best choice next; } next if ($self->{cfg}->{noignoredquotes} and $self->{ignorewords_regexp} and $random =~ /$self->{ignorewords_regexp}/i); $out = $random; } return $out || $out2; } sub _uniquify_nicks { my ($stats) = @_; foreach my $word (keys %{ $stats->{wordcounts} }) { if (my $realnick = lc(is_nick($word))) { if ($realnick ne $word) { # word is always lc $stats->{wordcounts}{$realnick} += $stats->{wordcounts}{$word}; $stats->{wordnicks}{$realnick} ||= $stats->{wordnicks}{$word}; $stats->{word_upcase}{$realnick} ||= $stats->{word_upcase}{$word}; delete $stats->{wordcounts}{$word}; delete $stats->{wordnicks}{$word}; delete $stats->{word_upcase}{$word}; } } } } sub _strip_mirccodes { my $line = shift; # boldcode = chr(2) = oct 001 # colorcode = chr(3) = oct 003 # plaincode = chr(15) = oct 017 # reversecode = chr(22) = oct 026 # underlinecode = chr(31) = oct 037 # Strip mIRC color codes $line =~ s/\003\d{1,2},\d{1,2}//go; $line =~ s/\003\d{0,2}//go; # Strip mIRC bold, plain, reverse and underline codes $line =~ s/[\002\017\026\037]//go; return $line; } sub checkname { # This function tracks nickchanges and puts them all in a hash->array, # so we can show all nicks that a user had later (only works properly # when nicktracking is enabled) my ($nick, $newnick, $stats) = @_; $stats->{nicks}{$newnick}{lc($nick)} = $nick; } sub _adjusttimeoffset { my ($self, $hour) = @_; if ($self->{cfg}{timeoffset} != 0) { # Adjust time $hour += $self->{cfg}{timeoffset}; $hour = $hour % 24; } return sprintf('%02d', $hour); } sub _read_cache { my ($self, $statsref, $linesref, $logfile) = @_; my $mtime = (stat $logfile)[9]; my $cachefile = $logfile; $cachefile =~ s/[^\w-]/_/g; $cachefile = "$self->{cfg}->{cachedir}/$cachefile"; return undef unless -e $cachefile; open C, $cachefile or die "$cachefile: $!"; local $/; my $str = ; close C; my ($stats, $lines); eval $str; return undef if $stats->{version} and $stats->{version} ne $self->{cfg}->{version}; return undef unless $stats->{logfile} eq $logfile; # the name might be ambigous return undef if $stats->{logfile_mtime} != $mtime; # file has changed print "cached, " unless $self->{cfg}->{silent}; $$statsref = $stats; $$linesref = $lines; return 1; } sub _update_cache { my ($self, $stats, $lines, $logfile) = @_; my $mtime = (stat $logfile)[9]; my $cachefile = $logfile; $cachefile =~ s/[^\w-]/_/g; $cachefile = "$self->{cfg}->{cachedir}/$cachefile"; #print "Writing cache $cachefile..."; $stats->{logfile} = $logfile; $stats->{logfile_mtime} = $mtime; unless (open C, ">$cachefile") { die "$cachefile: $!"; } $stats->{version} = $self->{cfg}->{version}; print C Data::Dumper->Dump([$stats], ["stats"]); print C Data::Dumper->Dump([$lines], ["lines"]); close C; } sub _merge_stats { my ($self, $stats, $s) = @_; my $days_offset = $stats->{days}; my $days_rollover = $stats->{oldtime} > $s->{firsttime}; $stats->{days} += $s->{days} - 1 + $days_rollover; foreach my $key (keys %$s) { #print "$key -> $s->{$key}\n"; if ($key =~ /^(logfile|firsttime|days|version)/) { # don't merge these next; } elsif ($key =~ /^(oldtime|lastnick|lastnormal|monocount)$/) { # {key} = int/str: copy $stats->{$key} = $s->{$key}; } elsif ($key =~ /^(parsedlines|totallines)$/) { # {key} = int: add $stats->{$key} += $s->{$key}; } elsif ($key =~ /^(wordnicks|word_upcase|urlnicks|chartnicks|smileynicks)$/) { # {key}->{} = str: copy foreach my $subkey (keys %{$s->{$key}}) { $stats->{$key}->{$subkey} = $s->{$key}->{$subkey}; } } elsif ($key =~ /^(nicks|karma)$/) { # {key}->{}->{} = str: copy foreach my $subkey (keys %{$s->{$key}}) { foreach my $value (keys %{$s->{$key}->{$subkey}}) { $stats->{$key}->{$subkey}->{$value} = $s->{$key}->{$subkey}->{$value}; } } } elsif ($key =~ /^(word|line|sex_line)_times$/) { # {key}->{}->[] = int: add foreach my $subkey (keys %{$s->{$key}}) { foreach my $pos (0 .. @{$s->{$key}->{$subkey}} - 1) { $stats->{$key}->{$subkey}->[$pos] += $s->{$key}->{$subkey}->[$pos] if $s->{$key}->{$subkey}->[$pos]; } } } elsif ($key eq 'lastvisited') { # {key}->{} = int: copy foreach my $nick (keys %{$s->{lastvisited}}) { $stats->{lastvisited}->{$nick} = $days_offset + $s->{lastvisited}->{$nick} - 1 + $days_rollover; } } elsif ($s->{$key} =~ /^HASH/) { # {key}->{} = int: add foreach my $subkey (keys %{$s->{$key}}) { die "$key -> $subkey" unless $s->{$key}->{$subkey} =~ /^\d+/; # assert $stats->{$key}->{$subkey} += $s->{$key}->{$subkey}; } } elsif ($key =~ /^topics$/) { # {key}->[] = topic hash: append push @{$stats->{$key}}, map { my %a = %$_; $a{days} += $days_offset - 1 + $days_rollover; \%a; # make new hash } @{$s->{$key}}; } elsif ($key =~ /^day_lines$/) { # {key}->[] = int: append my @list = @{$s->{day_lines}}; die if splice @list, 0, 1; # first element is always undef unless ($days_rollover) { $stats->{day_lines}->[$days_offset] += splice @list, 0, 1; } push @{$stats->{day_lines}}, @list; } elsif ($key =~ /^day_times$/) { # {key}->[]->[] = int: append outer list my @list = @{$s->{day_times}}; die if splice @list, 0, 1; if (not $days_rollover) { my @first = @{splice @list, 0, 1}; foreach my $pos (0 .. @first - 1) { $stats->{day_times}[$days_offset][$pos] += $first[$pos]; } } push @{$stats->{day_times}}, map { my @a = @$_; \@a; } @list; } else { die "unknown key format $key -> $s->{$key}"; } } } sub _merge_lines { my ($self, $lines, $l) = @_; foreach my $key (keys %$l) { # sayings, actionlines, etc. foreach my $subkey (keys %{$l->{$key}}) { push @{$lines->{$key}->{$subkey}}, @{$l->{$key}->{$subkey}}; my $x = @{$lines->{$key}->{$subkey}}; splice(@{$lines->{$key}->{$subkey}}, 0, ($x - 15)) if ($x > 30); } } } 1; __END__ =head1 NAME Pisg::Parser::Logfile - class to parse a normal logfile =head1 DESCRIPTION C parses a logfile using the configuration variables set in the 'cfg' option passed to the constructor. =head1 SYNOPSIS use Pisg::Parser::Logfile; $analyzer = new Pisg::Parser::Logfile( { cfg => $self->{cfg}, users => $self->{users} } ); =head1 CONSTRUCTOR =over 4 =item new ( [ OPTIONS ] ) This is the constructor for a new Pisg::Parser::Logfile object. The first option must be a reference to a hash containing the cfg and users structures. =back =head1 AUTHOR Morten Brix Pedersen =head1 COPYRIGHT Copyright (C) 2001-2005 Morten Brix Pedersen. All rights resereved. Copyright (C) 2003-2005 Christoph Berg . This program is free software; you can redistribute it and/or modify it under the terms of the GPL, license is included with the distribution of this file. =cut pisg-0.73/gfx/0000775000076400007650000000000011705647720011637 5ustar wadewadepisg-0.73/gfx/blue-h.png0000774000076400007650000000016011705647720013520 0ustar wadewade‰PNG  IHDRª}2®7IDATÁ9€@ A©ÿ‘óD"|¬=#D×ý }œ5=¦Zd›ìå­%RD‰è%KÔ˜>fÖ?óý*û7„?\IEND®B`‚pisg-0.73/gfx/red-v.png0000774000076400007650000000015011705647720013360 0ustar wadewade‰PNG  IHDR޾cm/IDATÓÁA °øÿÿôäÂc»vÄ›q·«œ)`’:0€1EºÊ·?Ç#*º¤œ¶`IEND®B`‚pisg-0.73/gfx/green-v.png0000774000076400007650000000015311705647720013711 0ustar wadewade‰PNG  IHDR޾cm2IDATÂA ÀøÿÍ<É¡,-»Db2©Ô¼.]4;‡¶¢m4 pB'Ë,*Åý ³“IEND®B`‚pisg-0.73/gfx/blue-v.png0000774000076400007650000000015211705647720013537 0ustar wadewade‰PNG  IHDR޾cm1IDATÓÁ1À0 @õÿ[ö>±SmˆE¹{ÖûÙg+œ€n¦©ªvÁE5Œ wF¹É¡*Þ÷¸{lIEND®B`‚pisg-0.73/gfx/yellow-v.png0000774000076400007650000000015111705647720014122 0ustar wadewade‰PNG  IHDR޾cm0IDATÓÁÁ ÁØÿÏ-Àß"ÜgÖ={¦à™ôD;°Ú*ËÈ…p2 ïÝ:+tuyöÑIEND®B`‚pisg-0.73/gfx/green-h.png0000774000076400007650000000016211705647720013673 0ustar wadewade‰PNG  IHDRª}2®9IDATÁ1€0DÁæß¿ð>É‚¸ 0ÏîçbŸÂÛQêÅ[+a),…•)FOT µ_üù¡+÷®IEND®B`‚pisg-0.73/gfx/yellow-h.png0000774000076400007650000000015611705647720014111 0ustar wadewade‰PNG  IHDRª}2®5IDAT ű 0”ÿ'>ä6ÔŠ’Td°<öšè.HT‚x ˆÇ”QöåÅ„Út? à+ßX¦IEND®B`‚pisg-0.73/gfx/red-h.png0000774000076400007650000000015611705647720013350 0ustar wadewade‰PNG  IHDRª}2®5IDATW%ŠI Ä`þê?=ÙÅ.ˆ•‹7åŽ2C©"™*ÈÍãMʧ›È|ÇðS*ׂUIEND®B`‚pisg-0.73/pisg0000774000076400007650000001232111705647720011741 0ustar wadewade#!/usr/bin/perl -w use strict; use Getopt::Long; # pisg - Perl IRC Statistics Generator # # Copyright (C) 2001-2005 - morten@wtf.dk # Copyright (C) 2003-2006 Christoph Berg # # 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA sub main { my $script_dir = $0; # If the script was executed as ./pisg - then we just remove # everything after the last slash, if it was executed as 'perl pisg' # we assume that we are executing in the current dir. if ($script_dir =~ m/\/[^\/]*$/) { $script_dir =~ s/\/[^\/]*$//; } else { $script_dir = "."; } if (!-t STDOUT) { # we are not writing to a terminal push @ARGV, "--silent"; } my $cfg = get_cmdline_options($script_dir); unshift(@INC, $cfg->{modules_dir}); my $version; if ($cfg->{version}) { $version = 1; undef $cfg->{version}; } my $pisg; eval < '1', override_cfg => \$cfg, search_path => \$script_dir, ); if (\$version) { print \$pisg->{cfg}->{version} . "\n"; } else { \$pisg->run(); } END if ($@) { print STDERR "Could not load pisg! Reason:\n$@\n"; return undef; } } sub get_cmdline_options { my $script_dir = shift; my %cfg = ( modules_dir => "$script_dir/modules/", # Module search path logfile => [], logdir => [], ); # Commandline options my ($tmp, $help, $silent, $option, @cfg); my $usage = < \$cfg{channel}, 'cchannels=s@' => \@{ $cfg{cchannels} }, 'logfile=s' => \@{ $cfg{logfile} }, 'format=s' => \$cfg{format}, 'network=s' => \$cfg{network}, 'maintainer=s' => \$cfg{maintainer}, 'outfile=s' => \$cfg{outputfile}, 'tag=s' => \$cfg{outputtag}, 'dir=s' => \@{ $cfg{logdir} }, 'nfiles=i' => \$cfg{nfiles}, 'prefix=s' => \$cfg{logprefix}, 'moduledir=s' => \$cfg{moduledir}, 'configfile=s' => \$cfg{configfile}, 'ignorefile=s' => \$tmp, 'aliasfile=s' => \$tmp, 'silent' => \$silent, 'version' => \$cfg{version}, 'cfg=s' => \@cfg, 'help|?' => \$help ) == 0 or $help) { die($usage); } if ($tmp) { die("The aliasfile and ignorefile has been obsoleted by the new pisg.cfg, please use that instead [see pisg.cfg]\n"); } if ($silent) { $cfg{silent} = 1; } if (@cfg) { foreach (@cfg) { if (/(.*)=(.*)/) { $cfg{lc $1} = $2; } else { print STDERR "Warning: Couldn't parse -cfg option\n"; } } } return \%cfg; } main(); # Run the script pisg-0.73/README0000774000076400007650000000506211705647720011740 0ustar wadewadeREADME, pisg - by me and others (see CREDITS file) ------------------ pisg - Perl IRC Statistics Generator, is a Perl script which takes IRC logfiles and turns them into nice looking stats, which can be amusing to show for the users of your channel. The supported logfile formats is explained in the FORMATS file included with this distribution in the 'docs' directory. SETTING UP PISG --------------- Full documentation for pisg is located in 'docs/pisg-doc.txt' and 'docs/html/index.html' for a HTML version. Quick usage instructions below: It's quite simple to set up pisg. You have 2 choices: * Set settings from commandline (try pisg --help) * Configure pisg from the pisg.cfg file (more flexible and configurable) If you look in the example pisg.cfg, you will see a small working sample where you can insert your own data. The commandline version has the disadvantage that you can only set up one channel to be run. RUNNING PISG ------------ If you have setup everything inside the config file, then you just need to run it. If you're on a Linux/BSD/Unix system, this should do the work: $ ./pisg Running pisg like this will just use the settings in pisg.cfg. If you want to specify things on commandline instead of in the config file, you could do: $ ./pisg -ch \#channel -l logfile.log -f mIRC -o index.html The syntax and options is explained when doing: $ ./pisg --help Setting settings on commandline, will override the relevant settings in pisg.cfg. NOTES ----- There is some graphics in the gfx/ folder which pisg uses, you should put these in the same directory as your stats file(s) or use the 'PicLocation' configuration option. The stats will look best with a logfile which is at least one day long. Some stats (like smilies, exclamation marks, etc) doesn't get counted before a special amount of time. pisg supports multiple languages so the texts on the stats page will be in your own language; look in lang.txt to see the supported languages. The language can be changed from within the pisg.cfg file. If you have any corrections to the language file, or you want to add a new translation, then send it to the mailing list. CONTACT INFORMATION ------------------- If you have any issues with pisg, such as problems with installing or running pisg, then send an e-mail to the pisg mailing list: http://lists.sourceforge.net/mailman/listinfo/pisg-general You can report bugs or add feature requests here: http://sourceforge.net/tracker/?group_id=31862 The pisg homepage is located at http://pisg.sourceforge.net/. Have fun :) - Morten Brix Pedersen pisg-0.73/pisg.cfg0000774000076400007650000000104311705647720012476 0ustar wadewade# Config file for pisg (set up all your channels/logfiles here) # # For a list of all configuration options, see docs/pisg-doc.txt or # docs/html/index.html for a HTML version. # # Here is some basic examples, uncomment them to make them actually do # something. # # # # # # # Logfile="channel2.log" # Format="mIRC" # Network="SomeIRCNet" # OutputFile="index.html" # # pisg-0.73/docs/0000775000076400007650000000000011705647720012003 5ustar wadewadepisg-0.73/docs/pisg-doc.txt0000664000076400007650000021562511705647720014264 0ustar wadewadepisg 0.73 documentation How to install and configure pisg __________________________________________________________ Table of Contents What is pisg? What are the requirements to run pisg? Setting up pisg for the first time Setting up a channel Specifying user options Setting global options Ignoring links Including common settings for various channels Changing the layout of your stats page Running pisg Obtaining help and reporting bugs General pisg options Channel -- define channel name Format -- the logfile format Network -- the IRC network of the channel OutputFile -- name of the generated HTML page OutputTag -- tag to insert into OutputFile Logfile -- name of logfile to parse LogDir -- parse a directory full of logs NFiles -- parse only the last files in LogDir Maintainer -- name of the maintainer ColorScheme -- use a different color scheme for stats page AltColorScheme -- alternate stylesheets for stats page Lang -- define the language / translation to use PageHead -- define a file as page header PageFoot -- define a file as page footer LogPrefix -- only parse logs LogPrefixed with a user defined string LogSuffix -- Regexp to sort logfiles by format month||day||year Silent -- make pisg silent, suppress messages CacheDir -- use a cache to speed up log parsing Options for various statistics features DailyActivity -- number of days to show in "Daily Actitity" ShowActiveTimes -- enable/disable "Most Active Times" ShowActiveNicks -- enable/disable "Most Active Nicks" ShowBigNumbers -- enable/disable "Big Numbers" sections ShowTopics -- enable/disable "Latest topics" sections ShowLines -- enable/disable "number of lines" ShowWpl -- enable/disable "words per line" ShowCpl -- enable/disable "characters per line" ShowWords -- enable/disable "number of words" ShowLastSeen -- show when a user was last seen on a channel ShowTime -- show when a nick was active ShowLineTime -- mIRCStats like behaviour of time bar ShowWordTime -- ShowLineTime like behavior of words column ShowRandQuote -- enable or disable the random quotes ShowLegend -- enable or disable the legend of the time bars ShowKickLine -- enable or disable the kick line ShowActionLine -- enable or disable the action line ShowShoutLine -- enable or disable the shout line ShowFoulDecimals -- set how many decimals to show ShowFoulLine -- enable or disable the foul line ShowViolentLines -- enable or disable the violent lines ShowMuw -- enable or disable "Most used words" ShowMrn -- enable or disable "Most referenced nicks" ShowMru -- enable or disable "Most referenced URLs" ShowCharts -- enable or disable channel music charts ShowOps -- enable or disable op statistics ShowVoices -- enable or disable voice statistics ShowHalfops -- enable or disable halfop statistics ShowMostNicks -- show who changed nick most often ShowActiveGenders -- show stats on which gender talked most ShowSmileys -- show most used smileys ShowKarma -- show channel karma ShowMostActiveByHour -- show most active nicks by hour ShowOnlyTop -- only count stats for top talkers, ignore less-active users ShowMostActiveByHourGraph -- show graphs in most active nicks by hour IgnoreWords -- ignore specified words NoIgnoredQuotes -- Control random quote output FoulWords -- specify words considered to be bad/FoulWords language ViolentWords -- specify words considered to be aggressive/violent MinQuote -- minimum numbers of letters for a random quote MaxQuote -- maximum numbers of letters for a random quote WordLength -- minimum number of characters in an interesting word QuoteWidth -- maximum allowed length of a "word" with no spaces BigNumbersThreshold -- Minimum number of lines per user for some "Big Numbers" statistics ActiveNicks -- nicks to show in "Most Active Nicks" ActiveNicks2 -- nicks to show in "These didn't make it.." ActiveNicksByHour -- number of nicks to show in "Most Active Nicks By Hour" MostNicksHistory -- maximum number of nicks to show in "users with most nicknames" MostNicksVerbose -- show nicks used in "most nicks" TopicHistory -- maximum number of topics to show UrlHistory -- maximum number of URLs to show ChartsHistory -- number of songs to show ChartsRegexp -- how to recognize songs played WordHistory -- maximum number of words to show NickHistory -- maximum number of nicks to show in "Most referenced nicks" SmileyHistory -- maximum number of smileys to show in smiley stats KarmaHistory -- maximum number of nicks to show in "Karma" NickTracking -- track nick changes and create aliases NickLimit -- maximum number of nicks in lists SortByWords -- sort "most active nicks" by words Picture options PicLocation -- path to images on stats page UserPics -- number of user pictures per row ImagePath -- path to user pictures (HTML page) DefaultPic -- use a default user picture ImageGlobPath -- path to user pictures (output generation) PicWidth -- define a standard width for user pictures PicHeight -- define a standard height for user pictures Misc options Charset -- character set to use for stats page LogCharset -- character set for logfiles LogCharsetFallback -- fallback character set for logfiles TimeOffset -- use a different time zone than the local machine RegexpAliases -- use regular expressions in user aliases LangFile -- filename of language file CssDir -- path to directory with CSS files HiCell, HiCell2 -- colors for color gradient in most active nicks section LogType -- type of log (not the format of the log) StatsDump -- dump raw statistics into file Copyright and License __________________________________________________________ What is pisg? pisg is an IRC statistics generator. It takes IRC logfiles and turns them into nice looking stats. In general, you would do something like this to get it running: * Enable logging in an IRC bot, or in your IRC client. The log will be outputted into a file. * You set up pisg, you define the channel name, and the path to the logfile you created. * You run pisg, pisg runs the log through and create statistics, it then creates an HTML page which you can upload to a webserver. __________________________________________________________ What are the requirements to run pisg? * An IRC client or bot where pisg supports the output logfile. * Any operating system which Perl runs on, this includes popular OSes such as Linux, FreeBSD, Windows and Mac. You will have a hard time finding an OS where Perl isn't supported. For Windows this means that you need to download ActivePerl. * Optional - a system to host the statistics page 24 hours a day, 7 days a week. * Optional - a system to log the channel, 24 hours a day, 7 days a week. __________________________________________________________ Setting up pisg for the first time Most configuration happens through the pisg.cfg file, the file format is made to be easy to read, and easy to extend for further use. It uses an XML-like format, with elements and attributes. __________________________________________________________ Setting up a channel An element called Channel is made for defining channels, a quick example of a channel is here: Logfile = "channel.log" Format = "mIRC" Maintainer = "John" OutputFile = "mychan.html" The above will define a Channel called #channel, the logfile pisg will look for is called channel.log and the Format of the logfile will be mIRC. The Maintainer (which will be stated on the output page) is John. That is basically it! Now, there are a lot more options that you can use for your channels, for this please refer to the reference documentation. Also be-aware of the fact that pisg uses various images to show the time-related bars. These images are placed in the gfx/ folder and should be placed into the same directory as your outputted HTML file. __________________________________________________________ Specifying user options User options are set with a simple XML-like syntax in the form: Remember, the nick is always required. For example to add aliases to a nick, then you could do this: The asterisk (*) means that it will match all nicks starting with 'Joe^'. So it will add all Joe^'s to 'Joe' in the stats. Another thing you can do is to add a picture to a user: If you have a larger picture of the user as well, you can make the picture on the stats page link to it: You can include * or ? to enable filename globbing to randomly choose one from several pictures: (see documentation for the ImageGlobPath option) You can also set a user's sex. The sex setting can be "f"emale, "m"ale, or "b"ot: Also you can add links to URLs and e-mails: or The last thing you can do is to ignore nicks (for example bots): You don't have to do all this in many lines, you could just as easily do: (Here the aliases are a space separated list of nicks, that also works! But * as a wildcard is smarter, although it is slower). __________________________________________________________ Setting global options Many times, it will be useful to set up global options, global options are set like this: Any global option will be overriden by anything defined within channel elements (see the Section called Setting up a channel) For example, to change the background color of the stats page, you could do: You can set many options in a single set: The above will set the language on the statistics page to DE (Deutsch, German) and set the time offset to +1. All options available are mentioned in the reference documentation. __________________________________________________________ Ignoring links It's possible to ignore links in the "Most referenced URLs" section: __________________________________________________________ Including common settings for various channels If you have, for example, more than one channel, where the users are the same, or you don't want to maintain more than one user file, you can use the "include" setting in the main config file: This will include the file /home/vetinari/pisg/users.cfg in the config at the place where the include statement is set. Note, that you can NOT include a file from an included file! __________________________________________________________ Changing the layout of your stats page The standard layout and colors in the outputted HTML page are made to be somewhat clean and neutral. But you have the chance to change the layout yourself. There are a few predefined color schemes for you to use, use the ColorScheme option when using them. The colorschemes distributed with pisg are: default (which is the default), darkgalaxy, darkred, justgrey, ocean, orange_grey, pisg, softgreen. When changing it, you need a fair knowledge of CSS (Cascading Style Sheets). CSS is what most of the web uses today to define styles and layout on HTML pages. With the pisg distribution, look in the layout directory. In it resides default.css which is the file being included onto the HTML page. Open it in a text editor like vi or notepad. Then change it until you're happy with it. Be aware that you might want to look at the HiCell and HiCell2 options through pisg.cfg for changing the last two colors. If you have created a nice stylesheet which other can take advantage of, you are encouraged to send it to the pisg mailing list so that it can be distributed with the next version of pisg. If you want to embed the statistics into another page, use the "none" color scheme. Pisg will then omit the HTML header and write only the body part. __________________________________________________________ Running pisg When everything is set up in the pisg configuration file (pisg.cfg), then you simply run pisg on the command-line. Using Linux, BSD or another UNIX-like system: user@host:pisg-0.37$ ./pisg Using Windows: c:\pisg> perl pisg The program will run and parse the logfiles you specified in the configuration file. If you are using Linux, BSD or another UNIX-like system and want run pisg automatically several times a day, then see the crontab file in the scripts/ directory. For Windows, see the windows-upload-ftp.txt file with the pisg distribution, this file is also placed in the scripts/ directory. __________________________________________________________ Obtaining help and reporting bugs If your problem could not be resolved through here, then you should send an e-mail to the pisg mailing list. You can subscribe and see more info at http://lists.sourceforge.net/lists/listinfo/pisg-general. If you believe that you have found a bug, you should use the SourceForge bug tracking system. __________________________________________________________ General pisg options Channel ----------------------- Channel option ----------------------- Channel -- define channel name Synopsis -------- Logfile = "channel.log" Format = "mIRC" Maintainer = "John" Description ----------- Channel is used in two contexts, globally when using and when defining new channels. It sets the name of the channel. Default Unset Format ----------------------- Format option ----------------------- Format -- the logfile format Synopsis -------- Logfile = "channel.log" Format = "eggdrop" Maintainer = "John" Description ----------- Format is used to define the format of the logfile, pisg supports a various number of different logfiles, see the FORMATS file included with the pisg distribution. If your logfiles have the suffix .gz or .bz2, they will automatically be decompressed and read by pisg. See also Maintainer. Default Unset Network ----------------------- Network option ----------------------- Network -- the IRC network of the channel Synopsis -------- Logfile = "channel.log" Format = "eggdrop" Network = "Undernet" Description ----------- Network is used to set the network which the channel resides on, this name is displayed on the stats page. Default SomeIRCNetwork OutputFile ----------------------- OutputFile option ----------------------- OutputFile -- name of the generated HTML page Synopsis -------- Logfile = "channel.log" Format = "eggdrop" OutputFile = "mychan.html" Description ----------- OutputFile is used to define the name of the generated statistics page. Default index.html OutputTag ----------------------- OutputTag option ----------------------- OutputTag -- tag to insert into OutputFile Synopsis -------- LogDir = "logs/" Format = "eggdrop" OutputFile = "mychan%t.html" OutputTag = "-week" Description ----------- OutputTag specifies a string that will replace occurrences of "%t" in OutputFile. This option is most useful when used as a command line switch (-t) to pisg in conjunction with NFiles (-nf). Example: $ pisg -co pisg.conf $ pisg -co pisg.conf -nf 8 -t -week Leaving out the OutputTag settings from the above pisg.conf snippet, this writes both the full statistics (mychan.html) and statistics for the last week (mychan-week.html) using the same pisg config file. (Assuming that there are separate logfiles for each day.) Default unset Logfile ----------------------- Logfile option ----------------------- Logfile -- name of logfile to parse Synopsis -------- Logfile="/home/foo/eggdrop/logs/mylog.txt" Format = "eggdrop" Description ----------- This defines the filename of the logfile to parse for the channel. If you want to parse a directory full of logfiles, you should use the LogDir option instead. Providing this option multiple times will parse multiple files in the order the statements appear. Wildcards (* ? []) will be expanded. See also LogDir and NFiles. Default unset LogDir ----------------------- LogDir option ----------------------- LogDir -- parse a directory full of logs Synopsis -------- LogDir="/home/foo/eggdrop/logs/" Format = "eggdrop" Description ----------- When LogDir is defined to valid path to a directory, then pisg will run through that directory, parse all logfiles in it and create one HTML page from it. Useful with for example eggdrop logs. Providing this option multiple times will parse all the files in multiple directories in the order the statements appear. See also NFiles, LogPrefix, and LogSuffix. Default unset NFiles ----------------------- NFiles option ----------------------- NFiles -- parse only the last files in LogDir Synopsis -------- LogDir="/home/foo/eggdrop/logs/" NFiles="8" Format="eggdrop" Description ----------- When NFiles is set to a positive integer, pisg will process only the last that much logfiles from Logfile and LogDir options. Useful to create statistics that cover the last week or month (assuming there are separate logfile per day/week/etc.). Default 0 (process all files) Maintainer ----------------------- Maintainer option ----------------------- Maintainer -- name of the maintainer Synopsis -------- Logfile = "channel.log" Format = "mIRC" Maintainer = "Benny" Description ----------- Maintainer is used to define the name of the maintainer of the statistics page, this can be either the person generating the stats or the bot/client doing the logging. The maintainer is displayed in the outputted stats page. This setting is also used by some log parsers where "You" is used instead of the nick in the log (e.g. "You have been kicked"). See also Format, NickTracking. Default MAINTAINER ColorScheme ----------------------- ColorScheme option ----------------------- ColorScheme -- use a different color scheme for stats page Synopsis -------- Logfile = "channel.log" ColorScheme = "darkgalaxy" Maintainer = "John" Description ----------- ColorScheme is used to define the color scheme used for the statistics page. Actually it's the CSS file being included. CSS files distributed with pisg are: darkgalaxy, darkred, default, justgrey, ocean, orange_grey, pisg, softgreen (omit the .css). The file will be included statically in the generated HTML page. If you give a file name or URL (i.e. a color scheme name with .css or a path), the file will be linked to instead. Using "none" will cause pisg to write only the body of the page; use this to include the statistics into a custom page. See also CssDir, AltColorScheme, HiCell/HiCell2. Default default AltColorScheme ----------------------- AltColorScheme option ----------------------- AltColorScheme -- alternate stylesheets for stats page Synopsis -------- Logfile = "channel.log" ColorScheme = "darkgalaxy" AltColorScheme = "layout/ocean.css" Maintainer = "John" Description ----------- AltColorScheme defines an alternate CSS file to be used for the statistics page. Multiple files can be given (space separated.) Note that this is not supported by all browsers. See also ColorScheme and CssDir. Default default Lang ----------------------- Lang option ----------------------- Lang -- define the language / translation to use Synopsis -------- Logfile = "channel.log" Format = "mIRC" Lang = "DE" OutputFile = "mychan-%l.html" Description ----------- Lang defines the language to use for the stats. Currently, lang.txt includes: EN (English), BG (Bulgarian), CA (Catalan), CZ (Czech), DA (Danish), DE (German), EE (Estonian), ES (Spanish), FI (Finnish), FR (French), GR (Greek), HE (Hebrew), HU (Hungarian), IS (Icelandic), IT (Italian), NL (Dutch), NL_BE (Flemish), NO (Norwegian), PL (Polish), PT (Portuguese), PT_BR (Portuguese/Brazil), RO (Romanian), RU (Russian), SE (Swedish), SI (Slovenian), SK (Slovak), SQ (Albanian), TR (Turkish), YU (Serbian). Output in several languages can be generated at the same time, separate the languages by comma. The tag %l in the output file name will be replaced by the language name. See also LangFile. Default EN (English) PageHead ----------------------- PageHead option ----------------------- PageHead -- define a file as page header Synopsis -------- Logfile = "channel.log" Format = "mIRC" OutputFile = "stats.html" PageHead = "myheader.txt" Description ----------- PageHead is used to include a file in the stats page, for example an introduction text, a link to an image or a banner. The file can hold anything, it will be included raw in the stats page - so HTML should be preferred. The file will be included in the top of the page. This option is the opposite of PageFoot. Default none PageFoot ----------------------- PageFoot option ----------------------- PageFoot -- define a file as page footer Synopsis -------- Logfile = "channel.log" Format = "mIRC" outputfile = "stats.html" PageFoot = "myfooter.txt" Description ----------- PageFoot is used to include a file in the stats page, for example an introduction text, a link to an image or a banner. The file can hold anything, it will be included raw in the stats page - so HTML should be preferred. The file will be included in the bottom of the page. This option is the opposite of PageHead. Default none LogPrefix ----------------------- LogPrefix option ----------------------- LogPrefix -- only parse logs LogPrefixed with a user defined string Synopsis -------- LogDir="/home/foo/eggdrop/logs/" Format = "eggdrop" LogPrefix = "logjun" Description ----------- When using the LogDir option and you only want to use a slew of the files in it, you can have pisg choose only files which are prefixed with a special string. Default unset LogSuffix ----------------------- LogSuffix option ----------------------- LogSuffix -- Regexp to sort logfiles by format month||day||year Synopsis -------- Description ----------- LogSuffix is used to define the suffix of a logfile, it only works when LogDir is defined. The example in the synopsis is for the eggdrop bots default format. Default Unset Silent ----------------------- Silent option ----------------------- Silent -- make pisg silent, suppress messages Synopsis -------- Description ----------- This option is useful mainly from command line when invoking pisg with --silent 1. But it can also used in the configuration file. It will suppress all standard output from pisg. Error messages will still be sent. Default 0 (disabled) CacheDir ----------------------- CacheDir option ----------------------- CacheDir -- use a cache to speed up log parsing Synopsis -------- Description ----------- Setting this option makes pisg dump the results of log parsing into cache files. The next time pisg is run, it compares the timestamp of the log(s) with the timestamp stored in the cache file. When the log was not changed, the cached data is used. (This means that it does not work if you only have a single big logfile. Split the log at arbitrary points and use LogDir or Logfile="dir/*".) Note that the cache files should be deleted when the pisg config file is changed since the cache data uses the old config settings. NickTracking does not work especially well with the cache when using different NFiles settings. Default Unset __________________________________________________________ Options for various statistics features DailyActivity ----------------------- DailyActivity option ----------------------- DailyActivity -- number of days to show in "Daily Actitity" Synopsis -------- Logfile = "channel.log" Format = "xchat" DailyActivity = "0" Description ----------- This option sets the number of days to show in the "Daily activity" section. Pisg will generate a graph that shows the actitivy during this timeframe. Setting the option to 0 disables the section. Default 0 (disabled) ShowActiveTimes ----------------------- ShowActiveTimes option ----------------------- ShowActiveTimes -- enable/disable "Most Active Times" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowActiveTimes = "0" Description ----------- With this option you can disable the "Most Active Times" section on the stats page. It will simply disappear when specifying 0. Default 1 (enabled) ShowActiveNicks ----------------------- ShowActiveNicks option ----------------------- ShowActiveNicks -- enable/disable "Most Active Nicks" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowActiveNicks = "0" Description ----------- With this option you can disable the "Most Active Nicks" section on the stats page. Default 1 (enabled) ShowBigNumbers ----------------------- ShowBigNumbers option ----------------------- ShowBigNumbers -- enable/disable "Big Numbers" sections Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowBigNumbers = "0" Description ----------- With this option you can disable the "Big Numbers" and "Other Interesting numbers" sections on the stats page. They will simply disappear when specifying 0. Default 1 (enabled) ShowTopics ----------------------- ShowTopics option ----------------------- ShowTopics -- enable/disable "Latest topics" sections Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowTopics = "0" Description ----------- With this option you can disable the "Latest topics" section on the stats page. It will simply disappear when specifying 0. Default 1 (enabled) ShowLines ----------------------- ShowLines option ----------------------- ShowLines -- enable/disable "number of lines" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowLines = "0" Description ----------- The default behaviour is to add a column to the "Most Active Nicks" section displaying the number of lines a user wrote. With this option it can be disabled. Default 1 (enabled) ShowWpl ----------------------- ShowWpl option ----------------------- ShowWpl -- enable/disable "words per line" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowWpl = "0" Description ----------- With this option you can enable the "words per line" column in the "Most Active Nicks" section. It will add a column describing the average words per line for a person. Default 0 (disabled) ShowCpl ----------------------- ShowCpl option ----------------------- ShowCpl -- enable/disable "characters per line" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowCpl = "0" Description ----------- With this option you can enable the "characters per line" column in the "Most Active Nicks" section. It will add a column describing the average number of characters per line for a person. Default 0 (disabled) ShowWords ----------------------- ShowWords option ----------------------- ShowWords -- enable/disable "number of words" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowWords = "0" Description ----------- The ShowWords option adds a column to the "Most Active Nicks" list which list the total number of words a user has typed. Default 0 (disabled) ShowLastSeen ----------------------- ShowLastSeen option ----------------------- ShowLastSeen -- show when a user was last seen on a channel Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowLastSeen = "0" Description ----------- With this option enabled, a column will be added to the "Most Active Nicks" section to display when a user was last seen. E.g. "2 days ago". Default 1 (enabled) ShowTime ----------------------- ShowTime option ----------------------- ShowTime -- show when a nick was active Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowTime = "0" Description ----------- The default behaviour is to add a column to the "Most Active Nicks" section displaying a fancy time bar to show when a user was active. With this option it can be disabled. Default 1 (enabled) ShowLineTime ----------------------- ShowLineTime option ----------------------- ShowLineTime -- mIRCStats like behaviour of time bar Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowLineTime = "0" Description ----------- The default behaviour is to add a column to the "Most Active Nicks" section displaying a fancy time bar to show when a user was active. With this option it can be done the same way as mIRCStats does it; that is, by putting that time bar next to the number of lines, in the same column. Default 0 (disabled) ShowWordTime ----------------------- ShowWordTime option ----------------------- ShowWordTime -- ShowLineTime like behavior of words column Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowWordTime = "0" Description ----------- The default behaviour is to add a column to the "Most Active Nicks" section displaying a fancy time bar to show when a user was active. With this option it can be done similarly to mIRCStats does it and like the ShowLineTime option, but using words instead of lines; that is, by putting that time bar next to the number of words, in the same column. Default 0 (disabled) ShowRandQuote ----------------------- ShowRandQuote option ----------------------- ShowRandQuote -- enable or disable the random quotes Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowRandQuote = "0" Description ----------- The default behaviour is to add a column to the "Most Active Nicks" section displaying a users random quote. With this option it can be disabled. Default 1 (enabled) ShowLegend ----------------------- ShowLegend option ----------------------- ShowLegend -- enable or disable the legend of the time bars Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowLegend = "0" Description ----------- By default, pisg shows a legend below the "Most Active Times" displaying what the different colors means. With this option it can be disabled. Default 1 (enabled) ShowKickLine ----------------------- ShowKickLine option ----------------------- ShowKickLine -- enable or disable the kick line Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowKickLine = "0" Description ----------- By default, pisg shows an example kick line in the "Most kicked"-stats. With this option it can be disabled. Default 1 (enabled) ShowActionLine ----------------------- ShowActionLine option ----------------------- ShowActionLine -- enable or disable the action line Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowActionLine = "0" Description ----------- By default, pisg shows an example action line in the "Most actions"-stats. With this option it can be disabled. Default 1 (enabled) ShowShoutLine ----------------------- ShowShoutLine option ----------------------- ShowShoutLine -- enable or disable the shout line Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowShoutLine = "0" Description ----------- By default, pisg shows an example shout line in the "Most shouting people"-stats. With this option it can be disabled. Default 1 (enabled) ShowFoulDecimals ----------------------- ShowFoulDecimals option ----------------------- ShowFoulDecimals -- set how many decimals to show Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowFoulDecimals = "2" Description ----------- By default, pisg uses 1 decimal. With this option you could change it to whatever you like. Negative is treated as the default value. Default 1 decimal ShowFoulLine ----------------------- ShowFoulLine option ----------------------- ShowFoulLine -- enable or disable the foul line Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowFoulLine = "0" Description ----------- By default, pisg doesn't show an example foul line in the "Most fouls"-stats. With this option it can be enabled. Default 0 (disabled) ShowViolentLines ----------------------- ShowViolentLines option ----------------------- ShowViolentLines -- enable or disable the violent lines Synopsis -------- Logfile = "channel.log" Format = "bobot" ShowViolentLines = "0" Description ----------- By default, pisg shows example violent lines in the "Most aggressive" and "Most attacked"-stats. With this option it can be disabled. Default 1 (enabled) ShowMuw ----------------------- ShowMuw option ----------------------- ShowMuw -- enable or disable "Most used words" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMuw = "0" Description ----------- By default, pisg adds an "Most used words" section to the stats page. With this option you can disable it from being shown. See also WordHistory. Default 1 (enabled) ShowMrn ----------------------- ShowMrn option ----------------------- ShowMrn -- enable or disable "Most referenced nicks" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMrn = "0" Description ----------- By default, pisg adds an "Most referenced nicks" section to the stats page. With this option you can disable it from being shown. See also NickHistory. Default 1 (enabled) ShowMru ----------------------- ShowMru option ----------------------- ShowMru -- enable or disable "Most referenced URLs" Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMru = "0" Description ----------- By default, pisg adds an "Most referenced URLs" section to the stats page. With this option you can disable it from being shown. See also UrlHistory. Default 1 (enabled) ShowCharts ----------------------- ShowCharts option ----------------------- ShowCharts -- enable or disable channel music charts Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowCharts = "0" Description ----------- With this option set, pisg creates a chart listing of the top songs played on the channel. See also ChartsHistory and ChartsRegexp. Default 0 (disabled) ShowOps ----------------------- ShowOps option ----------------------- ShowOps -- enable or disable op statistics Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowOps = "0" Description ----------- By default, pisg has op statistics in the "Most interesting numbers" section. Here you can disable the feature, it's useful if you don't feel that the information is of any value, or your log format doesn't support ops/deops. Default 1 (enabled) ShowVoices ----------------------- ShowVoices option ----------------------- ShowVoices -- enable or disable voice statistics Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowVoices = "0" Description ----------- By default, pisg doesn't have voice statistics like it has op statistics. Enabling this option will add a section to the "Most interesting numbers" displaying who got most voices. Default 0 (disabled) ShowHalfops ----------------------- ShowHalfops option ----------------------- ShowHalfops -- enable or disable halfop statistics Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowHalfops = "0" Description ----------- By default, pisg doesn't have halfop statistics (+h on some servers) like it has op statistics. Enabling this option will add a section to the "Most interesting numbers" displaying who gave most half-ops. Default 0 (disabled) ShowMostNicks ----------------------- ShowMostNicks option ----------------------- ShowMostNicks -- show who changed nick most often Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMostNicks = "0" Description ----------- By enabling this option, pisg will add a section to the stats showing who had the most nicks, and what the nicks were. This option only works properly when NickTracking is enabled or user aliases have been defined. See also MostNicksHistory, MostNicksVerbose, and NickLimit. Default 0 (disabled) ShowActiveGenders ----------------------- ShowActiveGenders option ----------------------- ShowActiveGenders -- show stats on which gender talked most Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowActiveGenders = "0" Description ----------- Setting this option will make pisg create statistics on which gender (female/male/bot) talked most (see the "sex" option in the Section called Specifying user options in the Chapter called Setting up pisg for the first time). See also NickLimit. Default 0 (disabled) ShowSmileys ----------------------- ShowSmileys option ----------------------- ShowSmileys -- show most used smileys Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowSmileys = "0" Description ----------- With this option, pisg will make a list of the most used smileys in the channel. See also SmileyHistory. Default 0 (disabled) ShowKarma ----------------------- ShowKarma option ----------------------- ShowKarma -- show channel karma Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowKarma = "0" Description ----------- With this option, pisg will analyze the channel karma. Users can give other users (or things) good or bad karma by saying "nickname++" or "nickname--"; "nickname==" resets it to zero. Only the last karma is remembered per nick/nick combination, so there is at most +- 1 karma point. See also KarmaHistory and NickLimit. Default 0 (disabled) ShowMostActiveByHour ----------------------- ShowMostActiveByHour option ----------------------- ShowMostActiveByHour -- show most active nicks by hour Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMostActiveByHour = "0" Description ----------- By enabling this option, pisg will add a section to the stats showing "Most Active Nicks By Hour" - also look at the ShowMostActiveByHourGraph and ActiveNicksByHour settings. Default 0 (disabled) ShowOnlyTop ----------------------- ShowOnlyTop option ----------------------- ShowOnlyTop -- only count stats for top talkers, ignore less-active users Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowOnlyTop = "1" Description ----------- By enabling this option, stats in the "Big Numbers" and "Interesting Numbers" section will only be counted for users who were the most active. E.g. users who appear in the "Most Active Nicks" section, as respected by the ActiveNicks and ActiveNicks2 options. See also BigNumbersThreshold. Default 0 (disabled) ShowMostActiveByHourGraph ----------------------- ShowMostActiveByHourGraph option ----------------------- ShowMostActiveByHourGraph -- show graphs in most active nicks by hour Synopsis -------- Logfile = "channel.log" Format = "xchat" ShowMostActiveByHourGraph = "0" Description ----------- By enabling this option and the ShowMostActiveByHour option, pisg will show graphs in the "Most Active Nicks By Hour" section. Default 1 (enabled) IgnoreWords ----------------------- IgnoreWords option ----------------------- IgnoreWords -- ignore specified words Synopsis -------- Description ----------- Sometimes words in the "most used words" appears which you don't want to see, with this option you can ignore these words. It also applies to the "most referenced nicks" section. It's a space separated list of words. You can use * like in nick aliases. Can not be used in a channel-only context. Default unset NoIgnoredQuotes ----------------------- NoIgnoredQuotes option ----------------------- NoIgnoredQuotes -- Control random quote output Synopsis -------- Description ----------- When set to "1", pisg will not output quotes containing ignored words. Pisg will output a blank line after trying 20 random quotes if all 20 random quotes were ignored. Default 0 FoulWords ----------------------- FoulWords option ----------------------- FoulWords -- specify words considered to be bad/FoulWords language Synopsis -------- Description ----------- There is a section in the "Most interesting numbers" which tells who had a "dirty mouth" - here you can define which words are considered being bad/foul. It is a space separated list of words. You can use * like in nick aliases. Can not be used in a channel-only context. Default ass fuck bitch shit scheisse kacke arsch ficker ficken schlampe ViolentWords ----------------------- ViolentWords option ----------------------- ViolentWords -- specify words considered to be aggressive/violent Synopsis -------- Description ----------- There is a section in the "Most interesting numbers" which tells who is most "aggressive" - here you can define which words are considered being "violent". It is a space separated list of words. You can use * like in nick aliases. Can not be used in a channel-only context. Default slaps beats smacks MinQuote ----------------------- MinQuote option ----------------------- MinQuote -- minimum numbers of letters for a random quote Synopsis -------- Logfile = "channel.log" Format = "xchat" MinQuote = "10" Description ----------- The random quotes displayed in the "Most Active Nicks" section will be picked from a length range. With this option you can change the minimum number of letters required for a random quote. Also see the MaxQuote option. Note that pisg will still choose a short quote if it cannot find a longer one. Default 25 MaxQuote ----------------------- MaxQuote option ----------------------- MaxQuote -- maximum numbers of letters for a random quote Synopsis -------- Logfile = "channel.log" Format = "xchat" MaxQuote = "70" Description ----------- The random quotes displayed in the "Most Active Nicks" section will be picked from a length range. With this option you can change the maximum number of letters required for a random quote. Also see the MinQuote option. Default 65 WordLength ----------------------- WordLength option ----------------------- WordLength -- minimum number of characters in an interesting word Synopsis -------- Logfile = "channel.log" Format = "xchat" WordLength = "10" Description ----------- The "Most Used Words" section on the stats page display the most used words. The default is that a word only appears if it is longer than 5 characters. With this option you can change that minimum. Default 5 QuoteWidth ----------------------- QuoteWidth option ----------------------- QuoteWidth -- maximum allowed length of a "word" with no spaces Synopsis -------- Logfile = "channel.log" Format = "xchat" QuoteWidth = "48" Description ----------- Pisg will automatically insert a space in words that have a length over the amount QuoteWidth is set to. When used in breaking up URLs it will insert a space in the displayed URL, but not in the actual URL referenced by the HREF. Default 80 BigNumbersThreshold ----------------------- BigNumbersThreshold option ----------------------- BigNumbersThreshold -- Minimum number of lines per user for some "Big Numbers" statistics Synopsis -------- Logfile = "channel.log" Format = "xchat" BigNumbersThreshold = "10" Description ----------- Pisg will ignore users with less than this setting lines in the "questions asked", "shouts loudest", "CAPSLOCK", "longest line", "most sad", and "most happy" sections. If the setting is "sqrt" (the default), it will be dynamically replaced with the square root of the number of lines of the most active nick. See also ShowOnlyTop. Default sqrt ActiveNicks ----------------------- ActiveNicks option ----------------------- ActiveNicks -- nicks to show in "Most Active Nicks" Synopsis -------- Logfile = "channel.log" Format = "mIRC" ActiveNicks = "50" Description ----------- With this option you can define how many nicks you want to appear in the "Most Active Nicks" section on the stats page. Default 25 ActiveNicks2 ----------------------- ActiveNicks2 option ----------------------- ActiveNicks2 -- nicks to show in "These didn't make it.." Synopsis -------- Logfile = "channel.log" Format = "mIRC" ActiveNicks2 = "25" Description ----------- With this option you can define how many nicks you want to appear in the "These didn't make it" section on the stats page. Default 30 ActiveNicksByHour ----------------------- ActiveNicksByHour option ----------------------- ActiveNicksByHour -- number of nicks to show in "Most Active Nicks By Hour" Synopsis -------- Logfile = "channel.log" Format = "mIRC" ActiveNicksByHour = "25" Description ----------- With this option you can define how many nicks you want to appear in the "Most Active Nicks By Hour" section on the stats page. Default 10 MostNicksHistory ----------------------- MostNicksHistory option ----------------------- MostNicksHistory -- maximum number of nicks to show in "users with most nicknames" Synopsis -------- Logfile = "channel.log" Format = "mIRC" MostNicksHistory = "2" Description ----------- With this option you can define how many nicks you want to appear in the "Users with most nicknames" section. See also ShowMostNicks and MostNicksVerbose. Default 5 MostNicksVerbose ----------------------- MostNicksVerbose option ----------------------- MostNicksVerbose -- show nicks used in "most nicks" Synopsis -------- Logfile = "channel.log" Format = "mIRC" MostNicksVerbose = "0" Description ----------- By disabling this option you can stop pisg from displaying all the nicks a user has had in the "Most used nicks" section. See also ShowMostNicks, MostNicksHistory, and NickLimit. Default 1 (enabled) TopicHistory ----------------------- TopicHistory option ----------------------- TopicHistory -- maximum number of topics to show Synopsis -------- Logfile = "channel.log" Format = "mIRC" TopicHistory = "2" Description ----------- With this option you can define how many topics you want to appear in the "Latest topics" section. Default 3 UrlHistory ----------------------- UrlHistory option ----------------------- UrlHistory -- maximum number of URLs to show Synopsis -------- Logfile = "channel.log" Format = "mIRC" UrlHistory = "2" Description ----------- With this option you can define how many URLs you want to appear in the "Most referenced URLs" section. See also ShowMru. Default 5 ChartsHistory ----------------------- ChartsHistory option ----------------------- ChartsHistory -- number of songs to show Synopsis -------- Logfile = "channel.log" Format = "mIRC" ChartsHistory = "10" Description ----------- This option sets the number of songs that will be show in the channel music charts. See also ShowCharts and ChartsRegexp. Default 5 (the Top Five) ChartsRegexp ----------------------- ChartsRegexp option ----------------------- ChartsRegexp -- how to recognize songs played Synopsis -------- Logfile = "channel.log" Format = "mIRC" ChartsRegexp = "(?:is )?(?:np:|(?:now )?playing:? |listening t o:? )(?:MPEG stream from)?\s*(.*)" Description ----------- This option is a perl regexp that is used to recognize songs played. Please tell the pisg mailing list if you have a better default. The regexp MUST contain a single () pair to extract the song name. See also the perlre(1) manpage, ShowCharts and ChartsHistory. Default "(?:np:|(?:now )?playing:? (?:MPEG stream from)?)\s*(.*)" WordHistory ----------------------- WordHistory option ----------------------- WordHistory -- maximum number of words to show Synopsis -------- Logfile = "channel.log" Format = "mIRC" WordHistory = "5" Description ----------- With this option you can define how many words you want to appear in the "Most used words" section. See also ShowMuw. Default 10 NickHistory ----------------------- NickHistory option ----------------------- NickHistory -- maximum number of nicks to show in "Most referenced nicks" Synopsis -------- logfile = "channel.log" format = "mIRC" NickHistory = "3" Description ----------- With this option you can define how many nicks you want to appear in the "Most referenced nicks" section. See also ShowMrn. Default 5 SmileyHistory ----------------------- SmileyHistory option ----------------------- SmileyHistory -- maximum number of smileys to show in smiley stats Synopsis -------- logfile = "channel.log" format = "mIRC" SmileyHistory = "3" Description ----------- At most this many smileys will appear in smiley stats. See also ShowSmileys. Default 10 KarmaHistory ----------------------- KarmaHistory option ----------------------- KarmaHistory -- maximum number of nicks to show in "Karma" Synopsis -------- logfile = "channel.log" format = "mIRC" KarmaHistory = "3" Description ----------- At most this many nicks will appear in the good and bad karma stats. See also ShowKarma and NickLimit. Default 5 NickTracking ----------------------- NickTracking option ----------------------- NickTracking -- track nick changes and create aliases Synopsis -------- Description ----------- Enabling this option will track nick changes as well as it can. It will then automatically create aliases for these nicks. Useful for ShowMostNicks and other stats. Nick tracking does not work for log formats that do not use the nickname for the person running the logger, but only show "You" there. See Maintainer. Default 0 (disabled) NickLimit ----------------------- NickLimit option ----------------------- NickLimit -- maximum number of nicks in lists Synopsis -------- Description ----------- This option trims lists of nicks to a maximum length, replacing the rest with "...". Setting to 0 disables trimming. Affected are the used nicks in the "Users with most nicknames" section, nicks in "Most active genders", and nicks in the "Good/bad karma by" columns. See ShowMostNicks, ShowKarma, and ShowActiveGenders. Default 10 SortByWords ----------------------- SortByWords option ----------------------- SortByWords -- sort "most active nicks" by words Synopsis -------- logfile = "channel.log" format = "xchat" SortByWords = "0" Description ----------- The default for the "Most Active Nicks" section - is to sort users by lines. Enabling this will sort it by words instead. Default 0 (disabled) __________________________________________________________ Picture options PicLocation ----------------------- PicLocation option ----------------------- PicLocation -- path to images on stats page Synopsis -------- Description ----------- The location to the pictures used on the stats page - not the user pictures but the different bars in "Most Active Times". Default Current directory UserPics ----------------------- UserPics option ----------------------- UserPics -- number of user pictures per row Synopsis -------- Logfile = "channel.log" UserPics = "no" Description ----------- UserPics allows you to configure the number of user pictures per row. Per default, one picture will be shown. Since pictures are usually higher than one line of text, this lets the table grow. With settings greater than 1, several pictures will be placed next to each other. A good setting would be UserPics=3 and pictures of size 60x60. Set UserPics to no or 0 to disable user pictures. The latter is useful if you share a user config file between channels and want to disable user pictures for some channels. Default yes (1) ImagePath ----------------------- ImagePath option ----------------------- ImagePath -- path to user pictures (HTML page) Synopsis -------- Logfile = "channel.log" Format = "mIRC" ImagePath = "userpics/" Description ----------- ImagePath defines the path to where user pictures are located, relative to the HTML page generated. The default is that user pictures is located in the same directory as the HTML page. Default current directory DefaultPic ----------------------- DefaultPic option ----------------------- DefaultPic -- use a default user picture Synopsis -------- Logfile = "channel.log" Format = "mIRC" DefaultPic = "not_available.jpg" Description ----------- DefaultPic defines a picture to be displayed for all users which have no other picture defined in the user element. This is good for showing "No picture available" or something. May contain globbing patterns, see ImageGlobPath below. Default unset ImageGlobPath ----------------------- ImageGlobPath option ----------------------- ImageGlobPath -- path to user pictures (output generation) Synopsis -------- Logfile = "channel.log" Format = "mIRC" ImageGlobPath = "users/" Description ----------- ImageGlobPath defines the path to the directory where user pictures are located, relative to the current directory. This setting is used to choose random pictures if ? or * (globbing characters) are used in the picture name. ? matches a single character, * matches a (possibly empty) string. The default is the ImagePath setting. (NB: This setting will be different from ImagePath if the latter is not relative to the current directory, e.g. if you are writing the HTML file outside of the current directory.) Default current ImagePath setting PicWidth ----------------------- PicWidth option ----------------------- PicWidth -- define a standard width for user pictures Synopsis -------- Logfile = "channel.log" Format = "mIRC" PicWidth = "500" Description ----------- PicWidth defines the standard width for user pictures. Setting the 'width' attribute of image-elements on the outputted stats page. See also PicHeight. Default unset PicHeight ----------------------- PicHeight option ----------------------- PicHeight -- define a standard height for user pictures Synopsis -------- Logfile = "channel.log" Format = "mIRC" PicHeight = "500" Description ----------- PicHeight defines the standard height for user pictures. Setting the 'height' attribute of image-elements on the outputted stats page. See also PicWidth. Default unset __________________________________________________________ Misc options Charset ----------------------- Charset option ----------------------- Charset -- character set to use for stats page Synopsis -------- Logfile = "channel.log" Format = "xchat" Charset = "utf-8" Description ----------- The pisg stats page defines a character set in a meta tag, this can be used if your country is using a different one than the default. Pisg will also use this setting to convert the language templates from LangFile if the language defines a source charset. Note: you also have to tell your webserver to transmit the charset to the browser. With Apache, use "AddDefaultCharset off" in the server config. Default iso-8859-1 LogCharset ----------------------- LogCharset option ----------------------- LogCharset -- character set for logfiles Synopsis -------- Logfile = "channel.log" Format = "xchat" Charset = "iso-8859-1" LogCharset = "utf-8" Description ----------- If LogCharset is set and different from Charset, pisg will convert the charset using Text::Iconv. Using this option slows down log processing. Default empty (no conversion) LogCharsetFallback ----------------------- LogCharsetFallback option ----------------------- LogCharsetFallback -- fallback character set for logfiles Synopsis -------- Logfile = "channel.log" Format = "xchat" Charset = "utf-8" LogCharset = "utf-8" LogCharsetFallback = "iso-8859-1" Description ----------- LogCharsetFallback defines a fallback charset for the LogCharset conversion. This is useful if you have mixed unicode/iso-8859-* logs. Pisg will first try the conversion from LogCharset. If that fails, LogCharsetFallback is used. Note that this only works for charsets where certain byte sequences are illegal, like UTF-8. (In short: LogCharset = utf-8, LogCharsetFallback = iso-8859-15 works, the other way round does not.) Default empty (no fallback conversion) TimeOffset ----------------------- TimeOffset option ----------------------- TimeOffset -- use a different time zone than the local machine Synopsis -------- Logfile = "channel.log" Format = "mIRC" Maintainer = "John" TimeOffset = "+5" Description ----------- By default, pisg uses the time of the local machine to display the time of the generated stats. Sometimes when you have a shell on an external box, and it's in another country, you want to use another time. This is accomplished by the TimeOffset command. Default +0 RegexpAliases ----------------------- RegexpAliases option ----------------------- RegexpAliases -- use regular expressions in user aliases Synopsis -------- Description ----------- Enabling this option will make all aliases in lines be parsed as regular expressions; this setting also applies to the IgnoreWords, FoulWords, and ViolentWords settings. Default 0 (disabled) LangFile ----------------------- LangFile option ----------------------- LangFile -- filename of language file Synopsis -------- Description ----------- With this option you have an alternative way to define the name and/or path to the language file. Usually you don't have to touch this option. Default lang.txt CssDir ----------------------- CssDir option ----------------------- CssDir -- path to directory with CSS files Synopsis -------- Description ----------- CssDir is used to define the paths to the CSS files (the ColorSchemes). Usually you don't need to change this. This setting is only used when statically including the CSS file. Default layout/ (in current directory) HiCell, HiCell2 ----------------------- Default option ----------------------- HiCell, HiCell2 -- colors for color gradient in most active nicks section Synopsis -------- Description ----------- HiCell and HiCell2 define the colors to be used for the color gradient in the most active nicks section. They should match your ColorScheme. When setting HiCell the empty string (""), pisg will not generate a color gradient; you might want to use this with ColorScheme="none" or AltColorScheme. Default #BABADD, #CCCCCC LogType ----------------------- LogType option ----------------------- LogType -- type of log (not the format of the log) Synopsis -------- Description ----------- The type of logs kept for your channel. Currently only "Logfile" is supported, so you don't need to change this option. Default Logfile StatsDump ----------------------- StatsDump option ----------------------- StatsDump -- dump raw statistics into file Synopsis -------- Description ----------- This option is intended for debugging pisg, but might be useful to process the parsed logs with another program. The file contains the %stats and %lines hashes in perl's Data::Dumper format. Default Unset __________________________________________________________ Copyright and License pisg - Perl IRC Statistics Generator Copyright (C) 2001-2005 Morten Brix Pedersen - Copyright (C) 2003-2005 Christoph Berg 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA pisg-0.73/docs/CREDITS0000774000076400007650000001335611705647720013035 0ustar wadewadeCREDITS go to... -- Original author and leading developer: -- Morten Brix Pedersen Major contributors: -- * Winfried Nessen * Jamie Cheetham * Sam Bingner * Christoph Berg | NFiles and UserPics options, wildcards for random user pictures, wildcard and regexp support for IgnoreWords, FoulWords, ViolentWords, charset conversion support, BigNumbersThreshold option, karma, music charts, parser cache ... * Torbjörn Svensson | ShowFoulDecimals and AltColorScheme options, multiple channels with same | name, multiple languages per run, lots of other fixes, pum.pl Other contributors: * Stefan aka Flyghost | Code contribution and fixes * P. Gnodde aka Shogun | Lots of feature enhancements and code cleanups, thanks! * Steve Tibold aka T0mcat | Tons of ideas * Markus Geiger | Alias/nick replacement * Joakim Sandström | Ideas and bugfixes * Ryan Ryttie | xchat logfiles request/help * Laocius | The features 'most used words' and 'most referenced nicks' * Luca (eni) | Reported a very small, but stupid bug with the xchat fileformat :) * kiss dess | Found a few minor bugs. And added replace_links() * S. William Schulz | Better commandline arguments, --help and fixed indenting problems with xchat logs, also fixed a critical thing with --format, --silent switch * Tim Hunter | 'shortest lines', 'most fouls', 'pageheader' and more. * Kim Ingemann (KimI) | Danish translation * Molator | French translation * Sheuron Azxe | Spanish translation * Gandalf the Grey | Polish translation and egg2mirc.awk script. * Andreas Blaafladt | Norwegian translation * Sascha Lüdecke | Compressed files, addition of --prefix, and sorting of files in logdirs * JaMiR0W | Portugese translation * Hanno Hecker (Vetinari) | Lots of feature additions and code cleanups, thanks! | Updates to German translation, some patches for words and the feature 'most words'. * Pyrofikiemaan | Dutch translation * Andreas Henriksson | Swedish translation * Anders Rune Jensen (Superduck) | Language specific dates on stats page * Christian Legler | New images for pisg * Phil Gregory | Regex support in user aliases, grammar corrections, huge changes to modularize pisg into packages/objects. | 'bigpic' user option * Patrick Aussems aka Zyk | New options: show_mrn, show_mru, show_muw, show_randquote * David Leadbeater | Flexibility to irssi logfiles. * Mouky | Updates to French template, grammar/gender/spelling corrections. * Kirler@paincreators | Finnish translation. * Ales Tepina | Slovenian translation * Gyuri Horak | Hungarian translation * Pascal Brax | Italian translation * deadlock | addalias.pl version 2, handling of users already in config file, obsoletin of addalias.htm and more configurable script. * Nicholas Frampton | infobot logfile support * Mo-Ize | zcbot logfile support * Azhrarn | winbot logfile support, Trillian logfile support windows-ftp-upload.txt addition * Andrew | axur logfile support * EQU | oer logfile support * "Travis Roy" | perlbot logfile support * Nathan Poznick | Ability to specify multiple LogFiles and LogDirs. * HM 2K | eggdrop-pisg.tcl for running pisg from eggdrop * Tiniduske | updated Dutch translation * Julien Danjou | pisg(1) manpage * coaster | improved mirc6hack.mrc * Vianney Lecroart | lulubot parser * Christian Garbs (mastermitch) | "Latest Topics" displays date * Jeroen van Nimwegen | updated Dutch translation * James Vega (jamessan) | Update for supy.pm * Tjavdar Ivanov | Update for Bulgarian * Axel 'XTaran' Beckert | pum.pl * Kresten Kjeldgaard | miau parser * Guilherme Barile | updated Portuguese/Brazil translation * Antoni GrzymaÅ‚a | updated Polish translation * NonExistenT | updated Russian translation * Silviu Foca | updated Romanian translation * Michal Stano | updated Slovak translation * Pavel Kouril | updated Czech translation * Sentence | updated Catalan translation * Lajos Galambosi | updated Hungarian translation * Gökhan | updated Turkish translation * Zoran | updated Serbian translation * Teemu Koskinen | patches to speed up karma parsing and code cleanup * Matti Peltola | Finish translation * skiidoo | updated French translation * KenjiE20 | weechat3 parser I probably forgot a lot of people here, _PLEASE_ notify me if I left you out.. because I have a bad habit of forgetting to maintain this list :) pisg-0.73/docs/FORMATS0000774000076400007650000004272311705647720013053 0ustar wadewadeSupported logfile formats by pisg ================================= This file contains a list of the different logfile formats which pisg supports. It also includes a sample line for these formats. If you don't have access to any of the clients/bots or you use some other IRC client/bot which isn't supported, then it's fairly easy to add support for a new IRC log format if you have some Perl knowledge, take a look at modules/Pisg/Parser/Format/Template.pm. If you don't have any Perl knowledge, then mail a sample logfile to the mailinglist (preferred as a link to the logfile) mIRC6 ----- - Version 6.x of mIRC - Same as mIRC except it uses a retarded logging format that makes modes indeciperable from actions (which is a nightmare to parse) - DON'T USE IT if you can avoid it, it doesn't do very well at understanding modes (see the "mIRC6hack" format) - In order to use this, format must be set to 'mIRC6'. - Remember to timestamp your logs, or it wont work, the timestamp must be in [HH:MM] or [HH:MM:SS] format. (logging options -> timestamp logs) mIRC6hack --------- - Version 6.x of mIRC using a logging script to produce a saner output - Same as mIRC6 except it uses '**' for actions - In order to use this, format must be set to 'mIRC6hack', and the following be added to mIRC's remote script section (Alt-R -> Remote): (thanks to virtuall and coaster) ------------------------------8<------------------------------ alias me { if ($1) { .describe $active $1- echo $color(own) -qt $active ** $me $1- } else { echo $color(info) $active * /me: insufficient parameters } } on ^*:ACTION:*:*:{ echo $color(action) -lt $iif($chan,$chan,$nick) ** $nick $1- haltdef } ------------------------------>8------------------------------ mIRC ---- - A client for Windows (www.mirc.com) - If you want to create mIRC logfiles with your eggdrop, you can get some TCL which does it all for you (also logrotating and much more). - MEL (mIRCStats Eggdrop Logger) can be downloaded from the following URL: http://mel.angelbears.org/ - Remember to timestamp your logs, or it wont work, the timestamp must be in [HH:MM] or [HH:MM:SS] format. - In order to use this, format must be set to 'mIRC'. Example: [23:44] Hello world XChat ----- - A client for Linux (www.xchat.org) - In order to use this, format must be set to 'xchat'. - Both the old logformat, and the new logformat from 1.8.7 and above is supported. Example of old logformat: 18:01:43 Hello world Example of new logformat: jan 13 04:39:42 Hello World XChat has changed its logformat again in early 2005. The "brand new" format is broken in the same way as the mIRC6 format in that it is now impossible to tell actions from real events. Additionally, the format of the lines in the log changed. It is possible to revert to the previous format (the one that pisg understands) by using the old text theme: http://xchat.org/files/themes/blacktheme.zip Eggdrop ------- - A cool and advanced IRC bot for Linux (www.eggheads.org) - In order to use this, format must be set to 'eggdrop'. You might want to change the logfile-suffix in order for pisg to parse the files in the correct order when using 'logdir': set logfile-suffix ".%Y%m%d" instead of the standard format set logfile-suffix ".%d%b%Y". Example: [00:02] Hello world Grufti ------ - A bot which I'm not really familiar with (www.grufti.com) - The author has actually made something like pisg called 'gruftistats', but someone mailed me and told me that it hadn't been maintained for over a year, and it had some problems.. - In order to use this, format must be set to 'grufti' Example: [00:17] Hello world bxlog ----- - A logging script for BitchX (console client - see scripts.bitchx.com) - In order to use this, format must be set to 'bxlog' - The bxlog-pisg.bx file in the scripts directory might be useful. Example: [31 Dec/11:26] Hello world mbot ---- - C-Based IRC Bot (http://darksun.com.pt/mbot/) - In the configuration file, timemode must be set to '1' - In order to use this, format must be set to 'mbot' Example: Thu Aug 23 12:59:40 2001 Hello world irssi ----- - Console IRC client (www.irssi.org) - Logfiles must be using the default theme in irssi. (The "(real name)" added by autorealname.pl is ok.) - In order to use this, format must be set to 'irssi'. - This format also works for ii (wmii) logs. Example: 17:40 <@John> Hello world psybnc ------ - IRC bouncer (http://www.psychoid.lam3rz.de/) - In order to use this, format must be set to 'psybnc' Example: 2001-08-19-23-14-06:#LINUX.DE::stelb!user@host.org PRIVMSG #linux.de :hi! winbot ------ - Windows-based IRC bot (http://www.winbot.co.uk/) - In order to use this, format must be set to 'winbot' Example: 15:32.58 17/10/2001 This is a normal line. zbot ---- - Bot written in C++ (http://zcbot.sourceforge.net/) - In order to use this, format must be set to 'zcbot' Example: 12/11/01 22:05:42 :Keitaro!KOala_v5@EVYRV4A4.ipt.aol.com PRIVMSG #alsa-station :Re all :-) ircle ----- - IRC client for Mac OS X - Support for this format is not completely done yet. - In order to use this, format must be set to 'ircle' Example: 6:35 PM: Sinnikal: thats gross infobot ------- - bot written in Perl (http://www.infobot.org) - In order to use this, format must be set to 'infobot' Trillian -------- - Trillian's IRC component. (http://www.trillian.cc) - Note: Your Logs must be timestamped in the format [%h:%m] or [%h:%m:%s] This is set in Preferences -> General -> Windows -> Display in your Trillian Client - Tested with Trillian Version 0.70 - In order to use this, format must be set to 'Trillian' bobot++ ------- - IRC bot written in C++. (http://pltplp.net/bobot++/) - In order to use this, format must be set to 'bobot' Example: [13/12/2001 - 20:38] hello world axur/epic --------- - A unix shell client similar to bitchx but not quite. - EPIC is available at http://www.epicsol.org/ - AXUR script for EPIC is available at http://www.asciifun.com/images/axur-2000.tar.gz or ax-b12r2.tar.gz axur/epic logs with two formats at once, one for normal users and one for the actual client doing the logging. Why? no idea. The normal format is of: [MM/DD/YYYY @ HH:MM:SS] saying [MM/DD/YYYY @ HH:MM:SS] * nick does some action here The loggers format is of: [MM/DD/YYYY @ HH:MM:SS] >(logger) saying [MM/DD/YYYY @ HH:MM:SS] >* logger does some action here Both are supported. Perlbot ------- - A bot which written in perl that supports loadable modules (http://perlbot.sourceforge.net) - It also has some modules for searching logs and some perl scripts for searching and browsing the log files. (See examples at http://stats.978.org) - Development on the bot seems to have stopped. I did need to edit it a bit to get it to log actions correctly. - In order to use this, format must be set to 'perlbot' Example: 13:22:57 bah, gotta run to the store oer / oer+MySQL --------------- - Bot written in C (http://oer.equnet.org/) - In order to use this, format must be set to 'oer' - oer support isn't finished, the example lines won't work so I suggest you set the following options in your config: - For a detailed description see: http://faq.equnet.org/?area=b2VyIGFuZCBvZXIrTXlTUUwgRkFR&id=35&lang=en Example: 1010866756 :EQU!equ@mira.equnet.org PRIVMSG #oer :test for mbrix muh --- - A bouncer for unix/linux (http://mind.riot.org/muh/) - In order to use this, format must be set to 'muh'. Since you can configure the log-format as you want to, the standard-format is used for parsing. In order to set it correctly add this to you muhrc: timestamptemplate = "[%a %d %b %H:%M:%S]"; Example: [Sat 16 Mar 21:24:09] hello everybody muh2 ---- - muh is a bouncer from muh.sf.net - muh2 is for the new version 2.2, see 'muh' for older versions. - In order to use this, format must be set to 'muh2'. Example: [11:23] Hello world [11:24] * carmen means that she is nice Energymech ---------- - An irc bot written in C which is currently beeing developed. - In order to use this, format must be set to 'energymech'. - Energymech is available at http://www.energymech.net or (better) at http://cvs.energymech.net Example: [00:02] Hello world [00:04] Joins: vjaway (vector@p5086F6EF.dip.t-dialin.net) Dancer ------ - Bot written in C (http://dancer.sourceforge.net/) - In order to use this, format must be set to 'dancer' Example: 15.57.40 # hello world! ViRC98 ------ - A client for Windows (http://www.hansprestige.com) at this time is ViRC2.0rc1 maybe the type of logs will change - Remember to timestamp your logs, or it wont work, activate it by checking "Client setup/ViRC '98 options/Chat logging/ (Miscellaneous logging options) Stamp every message logged with current time" - In order to use this, format must be set to 'virc98'. Examples: 01.15.39 [Fender] this is a normal line writen by myself 00.55.38 <@jax1n0^O> this is a normal line writen by another 22.24.27 * Fender says an action pircbot ------- - PircBot is a framework for an IRC Bot written in Java. It allows you to create your own custom IRC Bots using Java by building on the framework that is already provided by the PircBot. - Homepage: http://www.jibble.org/pircbot.php - In order to use this, format must be set to 'pircbot'. - Parses all data written by the bot as written by the nick assigned to 'maintainer' - Logs are timestamped with MILISECONDS since the epoch Example: 1013630386748 :nick!ident@hostname PRIVMSG #channel :Hello world. Eggdrop RacBot -------------- - the Eggdrop RacBot is an IRC bot, which dreived from the original eggdrop sources (see http://www.eggheads.org) - Homepage: http://www.racbot.org/ - In order to use this, format must be set to 'RacBot'. KVIrc ----- - A KDE client for Linux (http://www.kvirc.net/) - Support for this format is not completely done yet, actions and -/+o modes are not detected, so you should add to you config file: - Supports logs from version 2.x.x. v3.x.x or former versions has not been tested. - In order to use this, format must be set to 'kvirc'. Example: ### Log session started at Thu Aug 23 17:25:36 2001 ### [17:25:36] wwp [anonymous@AMontpellier-201-2-1-77.abo.wanadoo.fr] has joined #ECI [17:25:47] yop ### Log session terminated at Sun Sep 9 22:56:51 2001 ### moobot ------ - Python-based, modular IRC bot. - Turn on logging by adding an entry to the data table with type = 'logtype' and data = 'file' or 'date'. Add another entry with type = 'logfile' and data = the name of the file if type == 'file' or a string to be passed to strftime if type == 'date'. - The format name is "moobot". - All nicks are logged with their hostmasks, with the exception of those from the bot itself. (This may change in the future to have the bot's hostmask, too.) - Examples: 2002-07-06 00:05:29 :vergil!~vergil@host PUBMSG #space :mike_lap: i'm not joking, actually. 2002-07-04 15:56:19 :SpaceBot PUBMSG #space :huh? 2002-07-06 00:07:30 :vergil!~vergil@host CTCP #space :ACTION salutes 2002-07-18 10:37:18 :jeffcovey!~jeff@host KICK #space vergil :two days in a row! 2002-07-06.log:2002-07-06 12:07:41 :phil_tty!mjpr@host TOPIC #space : of course, god can go to rotters, for all she's managed not to do for me 2002-07-04 17:34:01 :jeffcovey!~jeff@host MODE #space +o CowBot 2002-07-04 12:02:42 :Leebert!~lsherida@host JOIN :#space 2002-07-04 18:24:18 :mike_lap!~emag@host NICK :Cathy ircII ----- - The original IRC client (http://www.eterna.com.au/ircii/) - In order to use this, format must be set to 'ircII' - You need to add a few on triggers to your .ircrc: on #^timer 50 "*0" echo $0 on #^timer 50 "*5" echo $0 to mark the time. They can be adjusted to taste (the above lines mark every 5 minutes), with the main effect being the topic change times will only accurate to how often the time is marked. - The config option "Maintainer" needs to be set to the maintainer's nick Example: 22:40 *** sonnlich (sonnloki@202.72.122.25348) has joined channel #unisfa * sonnlich waves. > evening rae Evening. DC++ ---- - Direct Connect Hub - In order to use this, format must be set to 'DCpp' - Not an IRC logger, rather a shared network botnet log - You MUST put botnicks into botnicks variable if you want to see kicks Example: sirc ---- - Simple IRC Client (http://www.iagora.com/~espel/sirc.html) - In order to use this, format must be set to 'sirc' - You must also load the sirc-timestamp.pl script in the scripts subdirectory into sirc (/load sirc-timestamp.pl after copying to appropriate location) dircproxy --------- - Detachable IRC Proxy Server (http://www.dircproxy.net/) - In order to use this, format must be set to 'dircproxy' - Currently does not recognize nick changes - apparently it logs nick changes to a separate file. As a result, nick tracking will not work. - This parser recognize both the 1.0.5 and the 1.1.0 log format. blootbot -------- - supports multiple channels, though the log will be parsed once for each channel - http://blootbot.sourceforge.net/ - In order to use this, format must be set to 'blootbot' Example: (also in the parser module) 01:02.03 normal 01:02.03 * nick/#channel action 01:02.03 >>> topic/#channel by nick -> topic... 01:02.03 >>> mode/#channel [+o nick] by ChanServ 01:02.03 >>> join/#channel nick (~user@example.com) 01:02.03 >>> kick/#channel [nick!~user@example.com] by nick (reason) 01:02.03 >>> nick_ materializes into nick HydraIRC -------- - HydraIRC is an open-source IRC client with an attractive and easy to use interface - http://hydrairc.sourceforge.net/ - In order to use this, format must be set to 'hydra' Example: [2003-02-22 16:49:18] *** Alexander changed topic to wibble [2003-02-22 16:52:29] Sorry about the delay. [2003-02-22 16:52:33] Slow. Waking. Up. [2003-02-22 16:52:34] *** Melody sets channel #ar-roleplay mode +v Alexander [2003-02-22 16:58:57] *** Kemmy|ZZZ changed nick to Kemayo [2003-02-22 17:03:34] * Alexander stirs Eien's brain. "Cooooooool..." rbot ---- - rbot is a ruby IRC bot. Think of him as a ruby infobot, with more and different features, and a nicer plugin scheme. - http://linuxbrit.co.uk/rbot/ - In order to use this, format must be set to 'rbot' Example: [2003/07/22 22:02:59] well, i'm considering setting up a cronjob or something to watch it [2003/07/22 22:03:11] hehe [2003/07/22 22:03:24] @ Mode +o Rathnor by ChanServ [2003/07/22 22:03:25] @ Quit: oddbudman: Remote closed the connection [2003/07/22 22:03:29] Rathnor: :( IRCAP ----- - Version 7.5 or 7.51 of IRCAP (www.ircap.com or www.ircap.net). - mIRC version 6.03 or 6.12 (this are the mIRC versions required by IRCAP, so not really a parser requirement). - Timestamp logs activated in mIRC: Enter Options (inside File -mIRC6.03- or Tools -mIRC6.12-), IRC->Logging and check Timestamp Logs. - To use this, format must be set to 'IRCAP'. Example: [2:51] a las wenassssssssss [2:51] [ArCePi] nas nas [2:51] [BruJo] wenas [2:51] lawyyyy Vision ------ - An irc client for BeOS ( http://vision.sourceforge.net and http://www.bebits.com/app/2623 ) - Timestamping has to be enabled in the preferences - The messages Vision displays for joins/parts/topic changes etc, is fully user configurable, this parses the default messages. If you have changed them in the preferences you have to edit the parser to reflect the changes. - In order to use this, format must be set to 'Vision' Supybot ------- - http://supybot.sf.net - Version tested with 0.77 - Log format : normal msg: [05-Mar-2004 17:28:10] * Jkx|home bon je vais pas trainer .. channel msg: [17-Feb-2004 08:13:47] *** Jkx changes topic to "Oh my god of topic JavaBot ------- - http://javabot.sourceforge.net - Version has to be 0.3.3 or newer - To use this, format must be set to javabot - Example: maj 07 21:11:44 a regular line maj 07 21:12:02 ---     CreoN sets mode +o scalldog maj 07 21:12:05 <--     CreoN has kicked JavaBot (JavaBot) maj 07 21:12:06 -->     JavaBot (~javabot@host.com) has joined #channel lulubot ------- - http://lulubot.berlios.de - Version tested with the CVS the 12/04/04 - Log format : [22-11-2004/14:42] *** Joined ace (~ace@154.25.145.85) [22-11-2004/15:00] morning [22-11-2004/15:01] * ace is back - Parser written by Vianney Lecroart weechat, weechat3 ----------------- - http://weechat.flashtux.org/ - There are two parsers, one for the old log format ("weechat"), and one for the new format starting from version 0.3 ("weechat3"). pisg-0.73/docs/dev/0000775000076400007650000000000011705647720012561 5ustar wadewadepisg-0.73/docs/dev/API0000774000076400007650000001062311705647720013121 0ustar wadewadeWith the advent of the modules, an API becomes necessary. This file is the place to document anything along those lines. The main parts of pisg operate by passing around a %stats hash. That hash is pretty big: Key Type Index Description -------------------------------------------------------------------------- words hash Number of words typed by given nick. wordcounts hash Number of times given word was used. wordnicks hash The last nick to use the given word. times hash Number of lines typed in the channel during the given hour (0..23). lines hash Number of lines typed by the given nick (both "normal" and action lines). line_times hash $line_times{nick}[index] index ranges from 0 to 3 and contains a count of the number of lines typed by that nick in the given time period. Each index is a 6-hour block. (e.g. 3 is from 18:00 to 23:59.) monologues hash Number of times the given nick had a monologue. sayings hash Random normal line from the given nick. questions hash Number of lines from the given nick that ended in question marks. shouts hash Number of lines ending in exclamation points. allcaps hash Number of lines in ALL CAPS. allcaplines hash Random line containing ALL CAPS. foul hash Number of lines containing foul words. foullines hash Lines containing foul words. smiles hash Number of lines containing smiling faces. frowns hash Number of lines containing sad faces. urlcounts hash Number of times each URL was mentioned. urlnicks hash Last nick to mention each URL. lengths hash Total length of all lines from the given nick. actions hash Number of actions. actionlines hash Random action line. violence hash Number of times the given nick attacked someone else. violencelines hash Random example of the given nick attacking someone. attacked hash Number of times the given nick was attacked. attackedlines hash Ramdom example of the given nick being attacked. gaveops hash Number of times the given nick granted ops. tookops hash Number of times the given nick removed ops. gavevoice hash Number of times the given nick granted voice. tookvoice hash Number of times the given nick removed voice. kicked hash Number of times the given nick kicked someone. gotkicked hash Number of times the give nick was kicked. kicklines hash Random example of the given nick being kicked. joins hash Number of times the given nick joined the channel. topics array Each array element is a hash with the following indices: topic - The new channel topic. nick - The person who set the topic. hour - The hour in which the change took place. min - The minute in which the change took place. days scalar Number of days the reporting period spanned. totallines scalar Total number of lines seen in file(s). parsedlines scalar Total number of parseable lines (normal, action, and third) seen in channel. processtime hash A hash containing 'hours', 'mins' and 'secs', describing the time elapsed while processing this channel. nicks hash A hash containing all nicks a user had through a logfile. The keys are the nicks, and the values is an array with their alternative nicknames. pisg-0.73/docs/Changelog0000774000076400007650000017151411705647720013630 0ustar wadewadepisg (0.73) - Wed Jan, 18th 2012 The "Long Awaited" Release. HM2K: * Migrated away from CVS to Git Christoph: * Add "listening to" to the default ChartsRegexp. Parsers: * New parser "weechat3" for weechat >= 0.3. * Update eggdrop parser for new logformat in 1.6.20 (timestamps with seconds). From http://buster-net.ru/. pisg (0.72) - Wed Feb, 13th 2008 The Not Quite Valentine's Day Release. Language Updates: + Spanish: remove extra quote char (thanks Angel Olivera). + German: included some patches by Alexander Schuch. + French: updated by skiidoo, thanks (SF #1892319). Torbjörn: * Parsers: + New parser for Konversation. Thanks ehein for the log. + New parser for Mozbot. Thanks Jon^ and Daeron for your work! + New parser for weechat. Thanks kelnoky for the log. Christoph: * Fix -ne option in manpage (thanks Justin Piszcz, Debian #430946). * Apply patch by Teemu Koskinen to use sprintf for rounding in HTMLGenerator.pm. pisg (0.71) - Wed Feb, 14th 2007 The Valentine's Day Release. Christoph: + Ship manpage source pisg.sgml in release, fix first paragraph. + IRCAP.pm has been in CVS for 3 years but wasn't shipped in the releases. Torbjörn: * Parsers: + Update for miau.pm for miau 0.6.x (mnh, jha) + Fix ShowOnlyTop to use only ActiveNicks (SF #1604942). + Add links in documentation on ShowOnlyTop. + Correct most used word/most referenced nick with cache (SF #1424050). Language Updates: + Finnish: updated by Matti Peltola with help from atheos and Daeron. + Estonian: fix lastseen1,2 (thanks Hannes Tarien). pisg (0.70) - Thu Sep, 14th 2006 Torbjörn: * Bug fixes: + Added missing '>' (SF #1550312). + Fix typo in docs (SF #1550765). Christoph: + The manpage file released with 0.69 was empty, sorry. Thanks to Julien Danjou for spotting. + Fix some typos in manpage and --help text. pisg (0.69) - Wed Aug, 31st 2006 Axel: * PISG Bug fixes: + Fixing several occurences of "Use of uninitialized value in substitution (s///)" (SF #1354920) * PUM Bug fixes: + Missing and unclear documentation in pum.conf * PUM Features: + Acknowledging the deletion of a user now with buttons instead of links so search engines won't follow the links and delete all users. + Raising PUM version to 3.2 Christoph: * Bug fixes: + Fix ActiveNicks2 display when ActiveNicks is not divisible by 5 (thanks to Ian Rutson). + Add patch by Teemu Koskinen to speed up karma parsing (SF #1489060). * Parsers: + Finally add miau parser by Kresten Kjeldgaard. Torbjörn: * Bug fixes: + Fix urlencode to encode '&' (thanks to Thomas Whaples). + Fix double class if hicell/hicell2 is set to "" (thanks RaZ for spotting this). + Fix bug when having multiplie languages defined and they use different charsets (iconv left to next language). + Fix tablewidthbug when running with multiplie outputs (thanks Daeron for this note). + Fix minortypo in HTMLGenerator.pm (thanks Daeron). + Fix wordcount (thanks Daeron). + Use nested HTML comments in CSS to cheat XML error having "" in the CSS file. + Fix title tooltip (SF #1492153). + Fix -cchannels option (SF #1369457). + Fix uninitialised values in charts (SF #1354920 and #1498999) + Fix Makefile to support the +CVS string and include it in releasename + Fix charts to not include "NULL" tracks. + Add note about compressed files (SF #1536186) * Features: + Add "+CVS" to versionstring and remove it in Makefile when running 'make release'. This makes snapshot easier. + Added some information about options pisg is run with to outputfile. * Parsers: + Add support for both the 1.0.5(stable) and the 1.1.0(devel) log format of dircproxy. + Fix parser for psyBNC (SF #1490957). + Update energymech to support new timestamp format. Language Updates: + Portuguese: completed by DarkForce72. + Portuguese/Brazil: completed by Guilherme Barile. + Spanish: completed by Sentence. + Hebrew: competed by goldan. + Polish: competed by Antoni GrzymaÅ‚a. + Italian: completed by X-Drum. + Russian: compeled by NonExistenT. + Romanian: completed by Silviu Foca. + Slovak: completed by Michal Stano. + Czech: completed by Pavel Kouril. + Catalan: completed by Sentence. + Estonian: completed by pilleriin. + Hungarian: completed by Lajos Galambosi. + Turkish: completed by Gökhan. + Serbian: splited into SR_EC and SR_EL by Sasa Stefanovic. + Slovenian: completed by HeadRoom. + French: updated by pam_. + Albanian: completed by Elian. + Swedish: minor update. pisg (0.68) - Mon Mar, 13th 2006 Christoph: * Bug fixes: + ColorScheme 'none' will generate the color gradient again, the gradient is dropped with HiCell="". + Fix parsing. + More smileys (SF #1264834). + Suppress output when not writing to a terminal. + Print full path when config file comes from the search path. + Strip [brackets] from chart titles. * Parsers: + Strip nick modes in xchat format (SF #1304262). + Add pointer to "compatibility" theme for XChat to FORMATS. + Add warning on silent option to eggdrop-pisg.tcl. + Note that the irssi format also works for ii (wmii). Torbjörn: * Features: + Generate stats in multiple languages in a single run. Language Updates: + English: Fix preposition (thanks, Barry Suridge). + French: completed by Yoda. + Estonian: Hannes Tarien. + German: Michael Weyershäuser. + Danish: more han/hun (he/she, thanks b0m). pisg (0.67) - Thu Aug, 18th 2005 Christoph: + Recognize ogg and wma suffixes in song stats, complain about invalid ChartsRegexp. + Documentation: Local options override global ones, not vice-versa. + Notes on using mIRC. + psybnc.pm: Fix ACTION pattern, require PRIVMSG on normal lines, fix thirdline pattern (SF #1251680). Torbjörn Svensson: + Added support for multiple channels in config with the same name. Even multiple channel directives for the very same channel are supported (closes SF tracker #967404). + Support 'bot' in addalias.pl. + Support the new Trillian format. + Chomp PageHead and PageFoot files. + Pisg User Manager (pum): replacement for addalias.pl (with Axel Beckert). + ColorScheme 'none' will now suppress the background color in "most active nicks" (closes SF #1255234). + Die if output cannot be written (closes SF #1207883); remove some redundant newlines. * Fix minor typo in 'justgrey' colorscheme * Languages: + Dutch: small update to shout1 (thanks, Søren Jensen). + Dutch/Flemish: new strings added (thanks, Jeroen van Nimwegen). + Finnish: new strings added (thanks, Mikko Nissinen and Matti Peltola). + Danish/Norwegian/Swedish: completed by Torbjörn Svensson. + Bulgarian: thanks, Tjavdar Ivanov. + Polish: fix attacked1 (thanks, kot_czarny, SF #1222407). + Greek: new strings (thanks, Konstantinos Tzanidis). + German: some minor tweaks. pisg (0.66) - Thu May, 13th 2005 Christoph: * Features: + Finally added support for 'asian' smiles ^^ (requested by Christian Garbs) and left-handed smiles (-8, improved the smiley regexps, and implemented new most used smileys stats. + Complain about invalid -cfg options (closes SF tracker #1183072 by nandmaster). * Cache: + Complain if CacheDir does not exist. + Note that caching does not work for "one big logfile" setups. + Latest topic was sometimes set -1 days ago (reported by Jarkko Seppelin). * Parser: + Update supy.pm for new log format (thanks to James Vega for the patch). + Add bxlog script supplied by Hannes Tarien. * Documentation: + Add correct ChartsRegexp. + Correct synopsis for ShowLines (thanks, Scelt). + Document DailyActivity (thanks coaster for spotting). * Bugfixes: + Change -n to -ne in --help output (thanks to Thomas Matthijs for the patch). + Fix picking MinQuote-length quotes (closes SF tracker #1183177 by nandmaster). + Continue after empty directories were found (closes SF tracker #1184874 by nandmaster). + Most referenced nicks now works for nicks containing upper case chars again (reported by Triper in SF tracker #1167424 and Scelt). + foul1 should talk about words instead of lines; fixed in Danish and French. + Fix music charts (reported by Daniel Jensen in SF #1195919). * Translations: + Updated Italian translation (thanks, Michele Venturi) + Fix typos in Estonian translation (thanks, Tegelane) pisg (0.65) - Fri Apr, 15th 2005 Christoph: * Karma didn't work well with nick aliases. It's still far from perfect, though (thanks to Nico for the test log). * Fixed breakage when multiple LogDirs were given (thanks to Toni Viemerö for the report, SF tracker #1155433). * Add channel owner (~) and admin (&) chars in various parsers (reported by Scelt in SF tracker #1170470). * Recognize "Short joins" in mIRC6 and mIRC6hack (thanks, coaster). The "Christoph got bored in Ireland" changes: * Get channel music charts with ShowCharts and ChartsHistory (suggested by Sven in SF tracker #1164596). * A CacheDir can now be used to dump the results of log parsing to files. See the documentation for details. * Debug option: StatsDump. * Made ShowLastSeen=1 and ShowMostActiveByHourGraph=1 default. * More verbose config parser error messages. * Most active nicks timebars have mouse-over titles. * Update copyright years and add copyright and license to documentation. Updated translations: * French (thanks, Sébastien Bourgeois). * Finnish (thanks, Sami Karuaho). pisg (0.64) - Thu Feb, 24th 2005 Morten: * Updated translations: + Swedish (thanks, Torbjörn Svensson) + Danish Christoph: * Updated translations: + Finnish (thanks, Sami Karuaho). + Estonian (thanks, Hannes Tarien). + Bulgarian (thanks, Dimitar and elseif). + Spanish (thanks, Anonymous). + Dutch (thanks, Jeroen van Nimwegen). + New translation: Flemish (copied from Dutch before the last update). + Norwegian (thanks, Andreas Blaafladt). * Modified the CSS files containing .male/.female classes to show sex color also for s (SF tracker #1088382 by Jeroen - tux2020). * Applied patch by Torbjörn Svensson for using alternate CSS files - thanks (AltColorScheme option). * Made Logfile accept wildcards, sanitized NFiles behaviour on multiple LogDirs. * No "Userpic" headline was shown when there were only DefaultPics. * Make "most used words" case-insensitive. * Make failure to read PageHead/PageFoot files non-fatal. * Applied patch by Hanno Hecker to keep only the last 50 quotes for each nick while parsing. Saves memory and is probably saner anyway (thanks!). * The "Latest Topics" section now displays the day like the "Last seen" column (introduce [:days] in the last seen templates, add [:date] in bylinetopic, swich [:nick] and [:time] around in English and German, lastseen1 is now "yesterday" in English/German/French - patches for other languages welcome!) (thanks, Christian Garbs). * Make the ircII format use Maintainer instead of ircIINick. * Documentation: + Add version number to title (and let the release Makefile update it). + Add note that Maintainer is used by some log formats. + State that NickTracking does not work for the Maintainer nick. pisg (0.63) - Wed Jan, 12th 2005 Morten: * A new option, ShowLines, for disabling the column with the number of lines in "Most Active Nicks" has been added. * Choose locally-installed pisg versions ahead of system-installed pisg versions. (thanks, Bruce W. Murphy) Christoph: * Updated translations: + German (thanks, Igge). + Greek (thanks, Konstantinos Tzanidis). + Hebrew (thanks, shimi). + Swedish (thanks, Torbjörn Svensson). * Inhibit warning in _mostreferencednicks when a nick is referenced before being used first. * Links for users in "These didn't make it to the top" (thanks, Edward Pinski). * irssi.pm: Recognize joins even when autorealname.pl is loaded. * Hint user to use a log with timestamps when no parseable lines are found. * Apply (and heavily sanitize) patch by Igge for "Most active genders" stats (enable with ShowActiveGenders="1"). * New karma statistics (ShowKarma, KarmaHistory options). * New NickLimit option (affects mostnicks, gender, and karma stats). * docs/pisg-doc.xml: more crossrefs and clarifications. * Fix subtle ignorewords issue. pisg (0.62) - Sat Dec, 11th 2004 Changes by Christoph Berg: * Update mIRC script for the mIRC6hack format (thanks, coaster). * Warnings about missing Text::Iconv are suppressed by 'silent'. * Make FoulWords, ViolentWords, and IgnoreWords configurable per channel (required quite some black regexp magic; SF tracker #1066103 by jjp3). * wordlist_regexp uses quotemeta. * New ShowActiveNicks option (defaulting to 1). * Added lulubot parser (thanks, Vianney Lecroart). * Yet another URL parsing fix (certainly not the last). * CSS file can be linked to instead of being included statically; using "none" will make pisg omit the HTML header. * Documented HiCell and HiCell2 options. * Fixed winbot parser (SF tracker #1082554 by Warmedal). Changes by Morten Brix Pedersen: * Fixed typo in French translation. pisg (0.61) - Sat Oct, 30th 2004 Changes by Christoph Berg: * Fix warning when running on empty logs. * Fix & conversion. * Rewrote URL/email parsing code (SF trackers #730899, #745483, #945302). * More nick sanitizing. * Remove whitespace around user pictures, border="0", title. * Formats: + New "mIRC6hack" format to work around braindead mIRC6 logging. + Fix topic parsing bug in eggdrop (SF tracker #739090 by flashcode). * docs/: + Nicer Makefile. + Write a single HTML file. + Various crossrefs. + Updated list of languages. + Grab pisg.sgml manpage from Debian package, update with new options. pisg (0.60) - Fri Oct, 15th 2004 Changes by Christoph Berg: * Clean up loop code in _mostnicks() and fix warning about calls to is_ignored(undef). * Added scripts/eggdrop-pisg.tcl for running pisg from eggdrop (thanks, HM2K). * Add total number of lines to status output. * Annotated all languages in lang.txt with charset; fixed some Russian and German strings. * Updated Norwegian translation (thanks, Andreas Blaafladt). * Updated Dutch translation (thanks, Tiniduske). * Fixed xchat2 "Topic for #chan is" parsing and added logsample (thanks, Brice Goglin). * Make BigNumbersThreshold accept only numbers and "sqrt" for security, use sqrt(most active nick's lines). * aspell'ed pisg-doc.xml. Changes by Morten Brix Pedersen: * Renamed the Danish translation to its correct abbreviation, DA instead of DK. * Updated Danish translation. * Fix problem with supybot log format, where the kick message became a part of a users nick. pisg (0.59) - Sun Oct, 3rd 2004 Changes by Morten Brix Pedersen: * Fix problem with number of rows shown when a nick has been ignored. (thanks, Chris Thornhill) * Update Windows documentation. Hopefully people will have less problems now. * alternative and title text in "active times" graphics are now the number of lines instead of percentage. Changes by Christoph Berg: * Make BigNumbersThreshold a perl expression; defaults to sqrt($lines). pisg (0.58) - Thu Sep, 9th 2004 Changes by Morten Brix Pedersen: * Added new option, ShowFoulDecimals which configures the number of decimals used in statistics in foul numbers. (thanks, Torbjörn Svensson) * Fix wrong references of nicks (thanks, Sascha Wessel) * HTML documentation now has sane filenames. * Documentation has been cleaned up for typos/spelling errors. * Replace PT translation with new one. The old one apparently wasn't European Portugese. (thanks, MrWho) pisg (0.57) - Sat Aug, 28th 2004 Changes by Christoph Berg: * Fix problem where NFiles didn't work when the specified values was more than the actual number of logfiles. * Sanitize nicks in _activenicks (fixes problem reported by shr3kst3r@hushmail.com/Andreas Blaafladt). * Added option BigNumbersThreshold to make previously undocumented behavior configurable. * Fixed warning when users didn't say any words. Thanks, Torbjörn Svensson. pisg (0.56) - Sat Jun, 19th 2004 * Fix parsing of energymech kick messages and modes (thanks, optika81) * Add colorscheme with traditional pisg (website) colors. Thanks, mite. * Fix many unitialized errors with rbot format. * Add Albanian (SQ) translation. Thanks, Elian. pisg (0.55) - Sun May, 30th 2004 * Added javabot support (thanks, Tobias Larsson) * Fix serious bug in mIRC/mIRC6 formats which caused lots of warnings to be outputted. * Distribute rbot.pm with release tarball, apparently it was lost at some stage. * Add LogCharset and LogCharsetFallback options. These can be used if your log file is in a encoding which isn't equal to your Charset variable. (thanks, Christoph Berg) pisg (0.54) - Thu Apr, 1st 2004 * Revert most of the performance improvement changes, they caused bugs. * Really fix topics with the mbot format. * Fix wrong recognizing of www URLs where "ewww" would be recognized as an URL. pisg (0.53) - Tue Mar, 23rd 2004 * Several noticeable performance improvements (thanks, Hanno Hecker) * mIRC is no longer the default format. You have to always specify a format now. * Fix wrong counting of most referenced nicks. * Remove devel-code that appeared in 0.52 pisg.cfg. * Added support for supybot logfiles,set format to 'supy'. (thanks, Jerome Kerdreux) * Fixed bug with uninitialised values in psybnc format. * Fixed problems with the mbot format where only the first word in a topic was shown. * Vision support wasn't being included with the tarball. Fixed. pisg (0.52) - Fri Feb, 13rd 2004 * Fixed a bug in the energymech format, it did not recognize join lines. * Fixed some bugs in the mIRC6 format. * Backwards-compatibility for old option names (which became deprecated in 0.37) has been removed. * PicWidth and PicHeight apparently got mixed up in the last version, fixed. * Multiple LogDirs and LogFiles can now be specified (thanks, Nathan Poznick) * Foul words no longer matches at the beginning or the end of the word. Eg. "ass" won't match "assembler" or "asshole" anymore. (thanks, Christoph Berg) * Support for wildcards/asterix in IgnoreWords, FoulWords and ViolentWords has been implemented. Eg. use "ass*" to accomplish the behaviour that was changed in the above entry. (thanks, Christoph Berg) * RegexpAliases now also applies to IgnoreWords, FoulWords and ViolentWords. (thanks, Christoph Berg) * Some minor layout changes (thanks, Christoph Berg) * Added Serbian (YU) translation (thanks, Garp) pisg (0.51) - Wed Jan, 21st 2004 * Fixed a bug in the irssi format where an action could be recognized as a normal line (thanks, Emil Mikulic) * Added a DailyActivity option, which shows the activity in the channel of the last N days. Disabled by default. (thanks, sektor). * Fixed wrong example documentation for PicWidth and PicHeight (thanks, Dennis Prebendorf). * (Previously undocumented) setting UserPics allows to turn on/off user pictures per channel and to place more than one picture per row to avoid blowing up the table's height. (Christoph Berg) * User pictures and DefaultPic may now contain * and ? to choose a random picture from ImageGlobPath. (Christoph Berg) * Made all picture heights integer. (Christoph Berg) * Add support for Vision logs (thanks, Vegard Wærp) * Timebars in "Most active users" now have a hover text which shows how many lines a used wrote in that period of a time (thanks, oxman) pisg (0.50) - Mon Nov, 17th 2003 * Added NFiles option, which can be used for LogDirs to only parse the last N files (thanks, Christoph Berg) * Added OutputTag option, which enables users to have variable output names (see documentation). (thanks, Christoph Berg) * Improve addalias.pl, allow upper case letters in nicknames. (thanks, Christoph Berg) * Emil Mikulic used 'pngcrush' on the .png files in gfx/ to make their size much smaller, thanks. You should overwrite your old png files with these new ones. * Distribute raw docbook (SGML) documentation (docs/pisg-doc.sgml) * Add half-op (+h) support to the xchat format (thanks, Jaff Har Har) * Fix a problem with irssi logs, where a topic was understood as a saying. (thanks, jikuja) * Add support for IRCAP logs (thanks, ArCePi) * Fix parsing of dircproxy logs (thanks, s-schwardt) pisg (0.49) - Sun Sep, 14th 2003 * Make the HTML output XHTML compliant again (thanks, Stian Jordet) * Add a bullet conversion character to Common.pm (thanks, Stian Jordet) * Added support for rbot logs (thanks, Anders Bach Nielsen) * Support for muh2 logs (muh 2.2 and later) (thanks, Sebastian Erlhofer) * Add hebrew language translation (thanks, shimi) * Add Bulgarian language translation (thanks, m9ck) * Updated Icelandic translation (thanks, Einar Jonsson) pisg (0.48) - Wed Apr, 29th 2003 * Add new option, MostNicksVerbose (enabled by default). When this option is disabled, instead of having a full list of nicknames in "most referenced nicks", only the number of nicks used will be listed. (thanks, David Lynch) * When no PicHeight is set, don't set the height attribute on images. Likewise with PicWidth. * Quote < and > to < and > even in non-default character set * Ignore more 'actions' in mIRC6 format that are actually status messages * Fix problem with muh format and action lines (thanks, Kevin Bralten) * The irssi logformat now also works when the timestamping includes seconds. * Added orange_grey colorscheme (thanks, maggic). * PicWidth and PicHeight settings now also works for DefaultPic option. pisg (0.47) - Wed Feb, 26th 2003 * Fix bug where multiple URLs in same line would have save name as first URL (EG: http://www.yahoo.com if yahoo was referenced first) * Update config parser to match the same character and only the same character (" or ') that started the quote to end the string. (Will now accept correctly, before it would have parsed it as . Will now NOT work with mis-matched quotes... which it probably never should have. EG: line should be inserted into the configuration file. Some users were confused about this. * Add config option "NoIgnoredQuotes" - will not output quotes containing ignored words if this is set. Will output a blank line after trying 20 random quotes if all 20 random quotes were ignored. * Add support for HydraIRC logfiles (thanks, David Lynch) * When a logfile had no matching lines according to the format, pisg outputted that no lines were found in the logfile. This was confusing because files in the wrong format usually contained lines. Now be more verbose. * ShowOps option added. Has similar effect as ShowVoices and ShowHalfops. pisg (0.46) - Tue Feb, 11th 2003 * Fix serious bug which caused garbled output i "Latest topics" and other places with URLs. * The default for the QuoteWidth option has been changed to 80. * Be in-casesensitive on charsets. * Small translations update to lang.txt pisg (0.45) - Wed Feb, 5th 2003 * Fix 3 small gramattical errors in english language. (thanks Cheetah) * Add half-op support to irssi format. (thanks, arsonist) * Fix a bug/crash with the DCpp format when a nick contained special characters. * Added justgrey colorscheme (thanks, Jens Bergmann) * Update URL for oer format in docs/FORMATS (thanks, EQU) * Update irssi format to accept 1 or more spaces before * for action lines instead of requiring 2 * Add modified version of patch from minicus - allows browser to split words at QuoteWidth number of characters into any given word, without splitting URL's (new config option) * When CharSet is not 'iso-8859-1' or 'iso-8859-15', don't provide conversions for characters. Fixes problems for many other languages, e.g. greek, korean etc. * Fix bug in mIRC6 format where it didn't recognize logfiles logging seconds * Fix bug in mIRC6 format where it didn't recognize kicks of the maintainer * Added support for sirc format (thanks bartko) * Added support for blootbot format (thanks, Tim Riker) * Added support for dircproxy format. * Move 'valign="middle"' statements out of blocks to blocks where they belong. According to HTML validator, valign is an invalid attribute for an statement. (see http://validator.w3.org/) pisg (0.44) - Sun Dec, 15th 2002 * Fixed an error in the mIRC6 format which caused pisg to abort on some lines. * mirc2egg script updated. * The random line in "Most Active Nicks" now wraps words that are longer than 40 characters. (thanks, glen) * Check if a userpic link begins with http:// -- if so, dont prepend image directory to URL * Look for a nick that has been referenced before in attacks, if one is not in the line fall back to using word following attack word * Chop lines added to sayings to the length of maxquote (so we don't have super long quotes showing up - BugID#594618) * Only match emails if it begins at the beginning of a line or after something other than ':' URL on that line. Fixes BugID#618540 * Strip DOS Formatting from files - Fixes space at end of line BugID#628580 * Fixed bug in hour tracking - Formats hours to 2 digits correctly now, previously was only forcing to 2 digit times if there was a time offset configured. Fixes BugID#632883 * Fixed bug - shouldn't have been grabbing 2 parts of the pircbot string to variables, was part of Rev 1.3 but apparently I forgot to actually put in that part. Thanks Marc Roberts for pointing this out. BugID#651485 * Added support for 'DC++' format, used by Direct Connect hub chat * Fixed bug in infobot format -- was matching any line that began lowercase as an action line. Infobot does not log actions in a recognizable format ... I even examined the output in hex to be sure. Fix BugID#652239 * Fixed a bug in logsuffix handling where pisg would blow up if the 'logsuffix' expression did not return dates for every filename. It will now not parse any files that logsuffix does not match. pisg (0.43) - Fri Nov, 22th 2002 * Add "ShowOnlyTop" option which can be used if you only want to have stats for the users which appeared in the "Most Active Nicks" (top talkers) section. (thanks, mincus) * Fix voice/devoice detection with xchat format. * mIRC6 format wasn't actually distributed with pisg, it is now. * mirc2egg.sed script added in the scripts/ folder, it's used to convert mIRC logs to eggdrop logs. (thanks, Geoff Simmons) * Hopefully fix xchat logs interpreting asterixs as the nick. * If a sex has been specified for a user in pisg.cfg, that user will now have a sex-dependent color in the stats page. (E.g. one color for males, another for females etc.) (thanks, Olivier 'Babar' Raginel) * For languages which have a general unknown-sex verb, this can now be specified. E.g. French has 'un' for male, 'une' for females and 'un(e)' as a general unknown-sex verb. (thanks, Gaël Roualland) pisg (0.42) - Fri Nov, 1st 2002 * ircII logfile support added (thanks, James Andrewartha) * Changed behavior of most active nicks to print an action line if no normal line is available for that nick * Added support for formatting of "for example" lines to standard format * Added retarded support for retarded logformat used for mIRC6.x * A bug in the zcbot format where the first character would be truncated has been fixed (thanks, Guillaume Leclanche) * New 'softgreen' colorscheme (thanks, Melody Mayberry) * Fixed wrong reference to PicHeight in docs which should be PicWidth. (thanks, J Lehto) * The ocean colorscheme has been updated, the link-hover color is now white. * A bug which appeared with some variations of xchat logfiles have been fixed. (thanks, Michael Hostbaek). pisg (0.41) - Sun Aug, 11th 2002 * Fix a bug in the winbot logfile format where lines containing the channel name in a wrong case wouldn't get counted. * Fix a bug in the mIRC format, where characters in the nick would be counted as mode changes. * When ShowTopics was set to 0, the headline "Latest topics" was still shown, fixed (thanks, Kean "zakarun" Pedersen) * New 'ocean' colorscheme (thanks, Mikko Nissinen) * New 'darkred' colorscheme (thanks, Hanno Hecker) * mIRC, Trillian, perlbot and virc98 formats now strips half-op prefixes from nicks as well. * moobot logfile support added (thanks, Phil Gregory) * Greek language support added (thanks, Konstantinos Tzanidis) pisg (0.40) - Thu Jul, 4th 2002 * The "It's Summer And The Sun Is Shining"-release. * When ShowMostAtiveByHour was enabled, unitialized values could appear which caused the HTML file not to be created. (thanks, Gissehel) * RacBot logfile support added (thanks, Hanno Hecker) * kvirc logfile support added (thanks, wwp) * Correct pircbot.pm to work with !channel, &channel and +channel in addition to #channel (thanks, Hanno Hecker) * Half-op statistics (+h), enabled by ShowHalfops. (thanks, crazycat) pisg (0.39) - Tue May, 14th 2002 * ShowFoulLine option added (thanks, Adam Spiers ). * The "foul-words" counting is now done word-wise instead of line-wise (thanks, Adam Spiers ) * Files in a LogDir is now run through alphabetically incase-sensitive (thanks, Gissehel ) * --prefix commandline option wasn't working, fixed. * Slovak translation added (thanks, Gabriel Svajko ) * Russian translation added (thanks, Anton Tretiakov, ) * A problem with links in Trillian log formats has been fixed (thanks, Hanno Hecker ) * A problem with multiple mode changes (+vv, +oo) in Trillian format has been fixed. * README has been polished/modified * It's now possible to include different configuration files using a new syntax (thanks, Hanno Hecker ) * Changes thanks to Matthew "Cheetah" Gabeler-Lee (): * A ShowWordTime option now exists that works the same as ShowLineTime, but uses word stats * SortByWords option added * Foul-words matching is now more strict. It no longer matches inside a word, but only in the end or at the start of a word * --cchannels commandline option added, when a channel is specified here, it will be the only channel to run stats for in pisg.cfg. * A bug previously that could cause pisg to error out in channels with untalkative users in the active list when sorting by words is fixed. * Random quotes wrap in the output html now pisg (0.38) - Thu Apr, 25th 2002 * Grammar fixes in documentation (thanks, Azhrarn ) * Added support for pircbot (http://www.jibble.org/pircbot.php) * Note added to docs/FORMATS file about oer format limitations (thanks, EQU ) * Icelandic translation added (thanks, Birkir ) * scripts/windows-ftp-upload.txt has been added; a sample script and description on how to upload files automatically on Windows. (thanks, Azhrarn) * A old configuration option appeared on commandline when doing pisg --help * Configuration options renamed: pic_width => PicWidth, pic_height => PicHeight, pic_loc => PicLocation. Documentation also added. * Split up the documentation of options into different categories, for better overview. * Fix minor typo in bxlog formats which caused joins to a channel not being registered properly (thanks, comcute ) * A dutch translation appeared in the English version of pisg; fixed. * Nicktracking wasn't working with the irssi logfile format, fixed (thanks, Matthäus Wander ) * Time-bars are now centered properly * Czech translation added (thanks, Jaroslav Ostadal ) pisg (0.37) - Mon Apr, 8th 2002 * The "lets clean up and move things around"-release * pisg.pl has been renamed to pisg * Colors/layout options has been removed. You now control the HTML page by using CSS. The 'layout' directory contains the default CSS file. Also, you are encouraged to provide your own CSS files for pisg so we can have different themes, send them to me and they will become a part of pisg :-) * Options has been renamed, the underscore has been removed, but they can still be used with a small warning. * prefix option has been renamed to LogPrefix * foul option has been renamed to FoulWords * The 'use_activetime_alt' option has been removed, not needed. * There is now an "MostNicksHistory" option to define how many nicks you want to have in the "Most Used Nicks" box * Some HTML columns were missing their end-tag when no voices had been made. Fixed. * It was not possible to use the LogSuffix option before, it's now working again. * 'names/name' is now translateable in the 'Most Used Nicks' section. * Remove CONFIG-README, obsoleted by new and better doc/pisg-doc.txt and doc/html/index.html * Nicks ignored are now properly ignored in 'Most Used Nicks' * pisg warned about an unrecognized line in the configuration file when you had empty lines in the channel section. Fixed. * When dealing with multiple channels; aliases, ignores etc. would get passed on to the next channel, so you could see nicks appearing which never existed on that channel. Fixed. This should also give a performance increase. * When using the TimeOffset option, the wrong hours was highlighted both in the vertical and horizontal bars - fixed. (thanks, Mircea Ionut Bardac) * When nicktracking is on, if a nick was changed but also appeared as a regex-alias, an errornous new alias would be created (thanks, Phil Gregory) * mIRC-logfiles were not recognizing nick-changes, fixed (Sam Bingner) * Support for muh-bouncer logs (thanks, Sebastian Erlhofer & Bastian Friedrich) * Support for dancer-bot logs (thanks, Elmar Hoffmann) * Support for energymech bot (thanks, Torsten Karwoth) * Support for virc98 logs (thanks, HceZar ) * Romanian translation added (thanks, Vlad ) * The usual translation updates. pisg (0.36) - Fri Feb, 8th 2002 * Many translation updates (thanks all) * Add new translation templates to translate the bottom of the stats page * Add Portugese/Brazil translation(PT-BR) (thanks Peter ) * addalias.pl script v2.2 by Jens Bergmann , see the changes in the README in scripts/addalias/ * The lang option is no longer case sensitive * "Most used nicks" no longer thinks that two differently cased nicks are different nicks. * Action lines fixed in axur format (thanks, Andrew ) * Fix serious bug in addalias.pl where a nick with a metacharacter in it would wipe out whole config (thanks for the report, Jens Bergmann) pisg (0.35) - Sat Jan, 26th 2002 * Translate mouse-over items (eg. "Open in new window: URL") * Support for oer bot logfiles (thanks to EQU ) * Support for perlbot logfiles (thanks to Travis Roy ) * Add -v / --version commandline option * Fix a rare bug where a user with only one line, and no words were causing unitialized values error. * Many fixes to axur logfile format (thanks, Andrew ) * Fix to irssi logfile handling, where a user was recognized as a mode (thanks, David Leadbeater ) * Support new xchat logfile format (from 1.8.6 and up) * Add "show_mostnicks" feature (thanks to "ST8" ), this adds a box on the stats page showing how many different nick uses people had * Fix bug in documentation, which said nicktracking was enabled by default, but it really isn't. * The addalias.pl script is no longer case sensitive when updating nicks already in the config file pisg (0.34) - Tue, Jan 8th 2002 * New option 'show_topics', to enable/disable 'last topics' * New feature 'bigpic' for users, see CONFIG-README. 'bigpic' will link to a bigger picture (thanks, Phil Gregory) * axur logfile support (thanks to Andrew ) * Nicks in 'most referenced nicks' is now being aliased properly, the "number of uses" wasn't being incremented for the aliases (thanks to Phil Gregory and The Paladin) * bobot++ logfile support added (thanks to Oct@zoy.org) * New option 'nickhistory' to define the maximum number of nicks in 'most referenced nicks' (as suggested by Zapp ) * The usual slew of translation updates pisg (0.33) - Tue, Dec 20th 2001 * The "Merry Christmas" release * Internet Explorer 6 centered all table contents, fixed. * Trillian logfile support added (thanks to Azhrarn ) * Remove a lot of debugging code which was never really used, this should give a small increase in performance * 'show_voices' wasn't working, fixed (thanks, Stefan D.) * Small bugfix to pisg.cfg parsing * Add 'pagefoot' option, works like the 'pagehead function' (thanks Jean Delvare) * Filter URLs with ampersands, & -> & (thanks Jean Delvare) * Changed README a bit * Add 'wordshistory' configuration option, to define how many words to be in 'most used words' pisg (0.32) - Sun, Dec 9th 2001 * infobot log support added by Nicholas Frampton * HTML changes: - Convert stats page to use more CSS, never use 'bgcolor' HTML attribute. - Make the page XHTML compatible, and use XHTML 1.0 Transititional doctype. * When a logfile had the same topic multiple times, all of the same topics was being shown on the stats page, now duplicate topics is removed. * The hour being highlighted in 'most active times' is now the hour with most activity, if you want to highlight the hour which the stats are being generated in, use 'use_activetime_alt' * More improvements to pisg.cfg parsing * irssi logfile fixes: - Was interpreting nicks with '-' in it incorrectly. - Topics wasn't being displayed correctly * All configuration options in CONFIG-README can now be specified on commandline, eg. 'pisg.pl --cfg show_wpl=1 --cfg show_cpl=1' pisg (0.31) - Mon, Dec 3rd 2001 * Fix serious bug where pisg would end up in an endless loop when multiple URLs were on a line. * More improved parsing: pisg will now complain if a configuration option is used, which doesn't exist in the real world. * Fix some documentation bugs * Report the right line number when displaying parse errors in pisg.cfg pisg (0.30) - Sun, Dec 2nd 2001 * New feature: 'show_lastseen' - will add a column in the stats to display when the user was last seen on the channel. * When using mIRC logs which have a prefix (eg. <@osama> hi!), the prefix will be removed automatically, works for both @ and +. * New 'urlhistory' option added to define the maximum number of URLs to show in 'most referenced URLs' * zcbot (http://zcbot.sourceforge.net/) support added by Mo-Ize * Preliminary support for 'ircle' logformats * Also translate the title of stats page * More precise docs, to document the defaults of the options. * When a topic or a line had multiple URLs/e-mails, only the first one was replaced by a link, fixed (thanks, Zapp ) * Add 'logsuffix' option, to get around problem with eggdrop logs not being sorted correctly. * 'wordlength' was applying to nicks in 'most referenced nicks' as well, don't do that. * Improved parsing of config file. pisg will now complain if a line isn't what it's supposed to be. * Lines with only a single smiley, eg. ' :P' got counted as a UPPERCASE line, now ignored. pisg (0.29) - Sat, Nov 10th 2001 * When using multiple channels, and not all channels have user pics, it was showing a big empty coloumn with no userpics. Now it checks whether any users in top xx has a userpic, and if yes, add the coloumn. * Additionaly, users can force pictures of a channel with the new 'userpics="n"' option. (This could be useful if a nick appears on many channels, but you only want the userpics on one..) * New version of addalias.pl by deadlock : - Doesn't need addalias.htm anymore, addalias.pl takes care of everything - Can dynamically change user data when a nick is already added in the config file - Improved error handling - Improved code * Can now show voices/devoices like the showing of ops/deops, disabled by default. Can be enabled with * A relative URL to the pisg image bars can now be defined with 'pic_loc', defaults to current dir. * Counted 'http://name.com/' differently from 'http://name.com' - fixed. * Fixed bug where mbot logs didnt count lines with only a 1 digit day value, thanks to Teemu Ikonen * Add support for winbot logfiles (www.winbot.co.uk) by Azhrarn * Updates to Swedish translation (thanks to Andreas Henriksson ) * Fix bug where when you had less than 5 urls in 'most referenced urls', one wasn't being shown. (thanks Hanno Hecker) * 'Hello' and 'hello' are no longer treated as seperate words in 'Most Referenced Words' * Added Estonian translation by comcute * Added Italian translation by Pascal Brax * Added Catalan translatino by Roger Utgés (Nikoru) pisg (0.28) - Sun, Oct 21th 2001 * Added Hungarian translation by Gyuri Horak * Performance improvements in HTML generation * Fix bug where the 'These didn't make it to the top' section wasn't being shown on the stats page when 'activenicks2' was less than the people in the top 25. * New options: - 'show_activetimes' enable/disable 'Most Active Times' section. - 'show_bignumbers' enable/disable 'Big Numbers' and 'Other Interesting Numbers' section. * The numbers below the timebars in 'Most Active Times' wasnt using the 'rankc' color option, it now does, and additionally adds a color 'hi_rankc' for highlighted ranks. * A topic like " blah blah blah" was showing up as "blah blah blah" in 'latest topics' - fixed. * Hopefully fix pisg on Win32. * Add charset to the HTML page to make validator.w3.org happy, it's user defineable with the new 'charset' option, default is 'iso-8859-1'. * The color of the links in the bottom of the page (not in tables) can be set by the new 'bg_link', 'bg_hlink' and 'bg_vlink' options. * New option: 'default_pic' makes it possible to display a default picture for a user if no picture defined. For example to display a picture showing 'No picture available.' pisg (0.27) - Sun, Oct 7th 2001 * Stats page was showing [:total] instead of the actual number, fixed. * Added Slovenian translation by Ales Tepina * Updates to various language templates * Cleaned up addalias script (scripts/addalias/), it now shows a prettier page, and it's now possible to add the sex of a user as well. * It's now possible to ignore unwanted URLs in 'most referenced urls': pisg (0.26) - Mon, Oct 1st 2001 * Internet Explorer interpreted width="" and height="" as a picture of 0x0 pictures, fix so we dont set empty values. * Updates to French template by Mouky and aNa|0Gue * Add --silent switch to pisg; makes pisg quiet, and only display error messages. (thanks, S. William Schulz) * Added Finish translation by Kirler@paincreators * Added missing template, 'bylinetopic', to translate "by on

$nickhelp
$txtalias:
$aliashelp
$txturl:
$urlhelp
$txtpic:
$pichelp
$txtsex:
$sexhelp
$txtignore:
$ignorehelp
HTML } sub readparams { $frm_nick = param('nick'); $frm_alias = param('alias'); $frm_link = param('link'); $frm_pic = param('pic'); $frm_sex = param('sex'); $frm_ignore = param('ignore'); } sub list { open(FILE, "<$pisg_config") or die("Error opening pisg config file: $!"); my $i = 0; my $nick; my $alias; while() { if($_ =~ /^\n \n $txtnick$txtalias \n"; foreach (@users) { if ($users[$i] =~ /nick=.*/) { if ($users[$i] =~ /nick="(\S+)"(.*)/) { $nick = $1; } if ($users[$i] =~ /alias="(\S+)".*/ or $users[$i] =~ /alias="(.*)"\s.*/ or $users[$i] =~ /alias="(.*)">/ ) { $alias = $1; } print " \n $nick$alias\n \n"; } $i++ } } sub read_config { open(FILE, "<$pisg_config") or die("Error opening pisg config file: $!"); my $i = 0; while() { if($_ =~ /^/ ) { $oldnicks{$nick[$i]}{'alias'} = $1; } if ($users[$i] =~ /link="(\S+)"(.*)/) { $oldnicks{$nick[$i]}{'link'} = $1; } if ($users[$i] =~ /pic="(\S+)"(.*)/) { $oldnicks{$nick[$i]}{'pic'} = $1; } if ($users[$i] =~ /sex="(\S+)"(.*)/) { $oldnicks{$nick[$i]}{'sex'} = $1; } if ($users[$i] =~ /ignore="(\S+)"(.*)/) { my $ignore = $1; if($ignore eq "y" or $ignore eq "Y") { $ignore = 1; } else { $ignore = 0; } $oldnicks{$nick[$i]}{'ignore'} = $ignore; } } else { $search = 1; } $i++; } return $search; } sub no_nick { print <Error: No Nickname given!
HTML ; } sub check_if_found { my $found = 0; my $lcnick = lc($frm_nick); foreach (@nick) { if (lc($oldnicks{$_}{'nick'}) eq $lcnick) { $found = 1; last; } } if ($found eq "1") { $old_nick = $oldnicks{$lcnick}{'nick'}; $old_alias = $oldnicks{$lcnick}{'alias'}; $old_link = $oldnicks{$lcnick}{'link'}; $old_pic = $oldnicks{$lcnick}{'pic'}; $old_sex = $oldnicks{$lcnick}{'sex'}; $old_ignore = $oldnicks{$lcnick}{'ignore'}; if ($old_sex eq "m" or $old_sex eq "M"){ $old_sexm = "checked"; } elsif ($old_sex eq "f" or $old_sex eq "F"){ $old_sexf = "checked"; } elsif ($old_sex eq "b" or $old_sex eq "B"){ $old_sexb = "checked"; } if ($old_ignore eq "1"){ $old_ignr = "checked"; } } return $found; } sub addinfo { my $line_to_add = ">$pisg_config") or die("Error writing to configfile: $!"); print FILE "$line_to_add\n"; close(FILE); $old_nick = $frm_nick; $old_alias = $frm_alias; $old_link = $frm_link; $old_pic = $frm_pic; $old_sex = $frm_sex; $old_ignore = $frm_ignore; if ($old_sex eq "m" or $old_sex eq "M"){ $old_sexm = "checked"; } elsif ($old_sex eq "f" or $old_sex eq "F"){ $old_sexf = "checked"; } elsif ($old_sex eq "b" or $old_sex eq "B"){ $old_sexb = "checked"; } if ($old_ignore eq "1"){ $old_ignr = "checked"; } print "$txtaddok

\n"; } sub updateinfo { my $line; my $line_to_add = "; close(OLDFILE); open(NEWFILE, ">$pisg_config") or die("Error updating configfile: $!"); &lock_file(*NEWFILE); foreach $line (@lines) { if ($line =~ /^$txtupdateok

\n"; } sub lock_file { my $lock = 2; flock($_[0], $lock); } pisg-0.73/scripts/windows-ftp-upload.txt0000774000076400007650000000403211705647720017047 0ustar wadewadeAUTOMATIC FTP UPLOAD BATCH FILE FOR WINDOWS ----------------------------- Batch file located in the bottom of this file. pisg.bat notes: --------------- Change the paths and such so they make sense with your config and have fun all you poor m$ users. ;) (NOTE: You may need to change the last line to 'ftp -s:%f0' on some old NT systems.) Basically just put all your ftp commands between the 'goto skip' and ':skip', and put any commands you want executed BEFORE IT (like pisg) at the end. The batch file will ignore the ftp stuff because of the goto, and the ftp script will ignore the one command it doesnt recognize(goto) with a small complaint and no error. Installation of .bat file: -------------------------- (described with Windows 2000 in mind) Go to Start->Settings->Control Panel->Scheduled Tasks Select "Add Scheduled Task. On the screen where it asks, browse to your batch file and hit next. Give the task a name (doesn't matter) Select "Perform this Task Daily". Start Time: 12:00 AM / Every Day / Start Date - default Enter in the account you want it to run as w/ the password. (I recomend an admin account, but it shouldn't matter) Check the []Open advanced properties box and hit Finish Go to the Schedule Tab. Click Advanced. Clear the End Date if it's checked. Check Repeat Task, put in every X hours (I have 6), and put duration to 24 hours. This should repeat the task in whatever increment you selected throught the day. Then it restarts the task on the next day. That should do it, play around with the settings until you think you have what you want. The way tasks are implemented are very wierd, but it works. ALso look into the 'at' command in the windows help for a command line version which may be easier to set up. -----------------------pisg.bat---------------------------- goto skip OPEN your.ftp.server.com username password CD /yourdir PUT "C:\Program Files\WinBot\Logs\pisg-0.37\index.html" QUIT :skip cd "C:\Program Files\WinBot\Logs\pisg-0.37\" perl "C:\Program Files\WinBot\Logs\pisg-0.37\pisg" ftp -s:%0 pisg-0.73/scripts/mirc2egg.sed0000774000076400007650000001745211705647720014751 0ustar wadewade#!/bin/sed -f # mirc2egg.sed: convert mIRC log to eggdrop format - 01/12/02 # Useful in replacing missing eggdrop logs # (supports mIRC 5.x, 6.x and 'Peace and Protection' formats) # # Usage: sed -f mirc2egg.sed channel.log > eggformat.log # # Geoff Simmons { # Remove carriage returns, delete single hyphen and blank lines s/ $// /^-$/d /^$/d # Strip color/formatting s/[0-9][0-9],[0-9][0-9]//g s/[0-9],[0-9][0-9]//g s/[0-9][0-9],[0-9]//g s/[0-9],[0-9]//g s/[0-9][0-9]//g s/[0-9]//g s///g s///g s///g s///g s///g s/—//g # Remove seconds from timestamp s/^\[\(..:..\):..\]/[\1]/ # PnP: reformat conversations to standard mIRC /^\[..:..\] (.*): /{ s/(//1 } # Extract channel name from header, convert to lower-case, # place in hold space, delete from pattern space /^\[..:..\] \*\*\* Now talking in #/{ s/.*\(#.*\)/\1/1 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ h d } /^Session Ident:/{ s/.*: \(.*\)/\1/1 y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ h d } # Change footer into end-of-log mark s/^Session Close: \(...\) \(...\) \(..\) \(..:..\):.. \(....\)/[\4] --- \1 \2 \3 \5/ # Retain conversations, actions and events - purge everything else /^\[..:..\] [<*-].*/!d # Remove op/voice tags from talking/actions s/^\[\(..:..\)\] <[@+]/[\1] /1 s/^\[\(..:..\)\] \*\*\*/[\1]/ s/^\[\(..:..\)\]/[\1] Nick change:/ } # Reformat nick changes (mIRC 6.x) /^\[..:..\] \* .*is now known as/{ s/is now known as/->/1 s/^\[\(..:..\)\] \*/[\1]/ s/^\[\(..:..\)\]/[\1] Nick change:/ } # Reformat quit actions (PnP) /^\[..:..\] \*\*\* Quits: .* (.*@.*\..*\..*)/{ s/\*\*\* Quits: //1 s/) (/) left irc: /1 s/)$// } # Reformat quit actions, append fake hostmask (mIRC 5.x) /^\[..:..\] \*\*\* Quits:/{ s/\*\*\* Quits: //1 s/] \(.*\) (\(.*\))$/] \1 (username@hostname.org) left irc: \2/ } # Reformat quit actions (mIRC 6.x) /^\[..:..\] \* .*) Quit.*)$/{ s/Quit/left irc:/1 s/^\[\(..:..\)\] \*/[\1]/ s/(//2 s/)$// } # Reformat part actions (mIRC 5.x) /^\[..:..\] \*\*\* Parts:/{ s/\*\*\* Parts: //1 s/) (\(.*\))$/) left irc: \1/ s/)$/) left irc:/ } # Reformat join actions (mIRC 5.x) /^\[..:..\] \*\*\* Joins:/{ s/\*\*\* Joins: //1 G s/\(.*\)\n\(#.*\)/\1 joined \2./1 } # Reformat join actions (mIRC 6.x) /^\[..:..\] \* .*) has joined/{ s/has //1 s/^\[\(..:..\)\] \*/[\1]/ G s/\(.*\)\n\(.*joined \)\(#.*\)/\2\1/1 s/\(.*joined\).*\n\(.*\)/\1 \2/1 s/$/./ } # Reformat kick actions (mIRC 5.x) /^\[..:..\] \*\*\* .*was kicked by.*)$/{ s/by \(.*\) (/by \1: (/1 s/was //1 s/kicked/kicked from /1 s/^\[\(..:..\)\] \*\*\*/[\1]/ G s/\(.*from \)\(.*\)\n\(.*\)/\1\3\2/1 s/(//1 s/)$// } # Reformat kick actions (mIRC 6.x) /^\[..:..\] \* .*was kicked by.*)$/{ s/by \(.*\) (/by \1: (/1 s/was //1 s/kicked/kicked from /1 s/^\[\(..:..\)\] \*/[\1]/ G s/\(.*from \)\(.*\)\n\(.*\)/\1\3\2/1 s/(//1 s/)$// } # Delete topic changes made by rejoining servers (mIRC 5.x) /^\[..:..\] \*\*\* .*\..*\..*changes topic to/d # Delete topic changes made by rejoining servers (mIRC 6.x) /^\[..:..\] \* .*\..*\..*changes topic to/d # Reformat topic changes, append fake hostmask (mIRC 5.x) /^\[..:..\] \*\*\* .*changes topic to/{ s/ changes topic to/!username@hostname.org:/1 s/^\[\(..:..\)\] \*\*\*/[\1]/1 s/^\[\(..:..\)\] /[\1] Topic changed on /1 G s/\(.*on \)\(.*\)\n\(.*\)/\1\3 by \2/1 s/'//1 s/'$// } # Reformat topic changes, append fake hostmask (mIRC 6.x) /^\[..:..\] \* .*changes topic to/{ s/ changes topic to/!username@hostname.org:/1 s/^\[\(..:..\)\] \*/[\1]/1 s/^\[\(..:..\)\] /[\1] Topic changed on /1 G s/\(.*on \)\(.*\)\n\(.*\)/\1\3 by \2/1 s/'//1 s/'$// } # Delete mode changes made by rejoining servers (mIRC 5.x) /^\[..:..\] \*\*\* .*\..*\..*sets mode: /d # Delete mode changes made by rejoining servers (mIRC 6.x) /^\[..:..\] \* .*\..*\..*sets mode: /d # Reformat multiple mode changes, append fake hostmask (mIRC 5.x) /^\[..:..\] \*\*\* .*sets mode: [+-][ovbntsmelkip][+-ovbntsmelkip ]/{ s/sets mode: //1 s/^\[\(..:..\)\] \*\*\*/[\1]/ s/^\[\(..:..\)\] \(.*\) \([+-].*\)/[\1] \2 '\3'/ G s/\] \(.*\) \('.*\)\n\(.*\)/] \3: mode change \2 by \1!username@hostname.org/1 } # Reformat multiple mode changes, append fake hostmask (mIRC 6.x) /^\[..:..\] \* .*sets mode: [+-][ovbntsmelkip][+-ovbntsmelkip ]/{ s/sets mode: //1 s/^\[\(..:..\)\] \*/[\1]/ s/^\[\(..:..\)\] \(.*\) \([+-].*\)/[\1] \2 '\3'/ G s/\] \(.*\) \('.*\)\n\(.*\)/] \3: mode change \2 by \1!username@hostname.org/1 } # Reformat single mode changes, append fake hostmask (mIRC 5.x) /^\[..:..\] \*\*\* .*sets mode: [+-][imtnselp]$/{ s/sets mode: //1 s/^\[\(..:..\)\] \*\*\*/[\1]/ s/^\[\(..:..\)\] \(.*\) \([+-].*\)/[\1] \2 '\3'/ G s/\] \(.*\) \('.*\)\n\(.*\)/] \3: mode change \2 by \1!username@hostname.org/1 } # Reformat single mode changes, append fake hostmask (mIRC 6.x) /^\[..:..\] \* .*sets mode: [+-][imtnselp]$/{ s/sets mode: //1 s/^\[\(..:..\)\] \*/[\1]/ s/^\[\(..:..\)\] \(.*\) \([+-].*\)/[\1] \2 '\3'/ G s/\] \(.*\) \('.*\)\n\(.*\)/] \3: mode change \2 by \1!username@hostname.org/1 } # Remove client-induced crap (mIRC 6.x) /^\[..:..\] \* Disconnected/d /^\[..:..\] \* Attempting to rejoin/d /^\[..:..\] \* Rejoined channel/d /^\[..:..\] \* Respond to/d /^\[..:..\] \* Retrieving #.*info\.\.\./d /^\[..:..\] \* Topic is/d /^\[..:..\] \* Set by/d /^\[..:..\] \* You/d /^\[..:..\] \* \/msg/d /^\[..:..\] \* Looking up.*user info/d /^\[..:..\] \* Timer vote/d /^\[..:..\] \* Break:/d /^\[..:..\] \* Waiting.*for previous request/d # Reformat actions s/^\[\(..:..\)\] \* /[\1] Action: / # Remove remaining crap /^\[..:..\] \*/d /^\[..:..\] \-/{ /-\{3\} /!d } } pisg-0.73/scripts/eggdrop-pisg.tcl0000774000076400007650000000276611705647720015652 0ustar wadewade#pisg.tcl v0.15 by HM2K - auto stats script for pisg (perl irc statistics generator) #based on a script by Arganan # WARNING - READ THIS # # If you use this script, PLEASE read the documentation about the "Silent" # option. If you get the message "an error occured: Pisg v0.67 - perl irc # statistics generator" in the channel, you are NOT running silent. Fix it. set pisgver "0.15" #Location of pisg execuitable perl script set pisgexe "/home/nf/pisg/pisg" #URL of the generated stats set pisgurl "http://stats.nemesisforce.com/" #channel that the stats are generated for set pisgchan "#nemesisforce" #Users with these flags can operate this function set pisgflags "nm" #How often the stats will be updated in minutes, ie: 30 - stats will be updated every 30 minutes set pisgtime "30" bind pub $pisgflags !stats pub:pisgcmd proc pub:pisgcmd {nick host hand chan arg} { global pisgexe pisgurl pisgchan append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" } puthelp $out } proc pisgcmd_timer {} { global pisgexe pisgurl pisgchan pisgtime append out "PRIVMSG $pisgchan :" ; if {[catch {exec $pisgexe} error]} { append out "$pisgexe an error occured: [string totitle $error]" } else { append out "Stats Updated: $pisgurl" } puthelp $out timer $pisgtime pisgcmd_timer } if {![info exists {pisgset}]} { set pisgset 1 timer 2 pisgcmd_timer } putlog "pisg.tcl $pisgver loaded" pisg-0.73/scripts/egg2mirc.awk0000774000076400007650000000212511705647720014747 0ustar wadewade#!/bin/awk # Quite fast log format converter (eggdrop->mirc) # For those channel stat generators that accept only mirc log format # use: awk -f egg2mirc.awk channel.log > mircformat.log # # Gandalf the Grey # "The Song Remains The Same" - Led Zeppelin # /\[..\:..\] <.+>/ { print $0 next } /\[..\:..\] Action:/ { $2="*" print $0 next } /\[..\:..\] .+ (.+) joined #/ { print $1 " *** " $2 " " $3 " has " $4 " " substr($5,1,length($5)-1) next } /\[..\:..\] .+ (.+) left #/ { print $1 " *** " $2 " " $3 " has " $4 " " substr($5,1,length($5)-1) next } /\[..\:..\] .+ (.+) left irc/ { print $1 " *** " $2 " " $3 " Quit (" $6 "...)" next } /\[..\:..\] .+ kicked from #/ { print $1 " *** " $2 " was " $3 " by " substr($7,1,length($7)-1) " (" $8 "...)" next } /\[..\:..\] #.+\: mode change / { if (index($NF,"!")!=0) print $1 " *** " substr($NF,1,index($NF,"!")-1) " sets mode: " substr($0,index($0,"'")+1,length($0)-length($(NF))-index($0,"'")-5) else print $1 " *** " $NF " sets mode: " substr($0,index($0,"'")+1,length($0)-length($(NF))-index($0,"'")-5)} pisg-0.73/scripts/crontab0000774000076400007650000000041411705647720014116 0ustar wadewade# In order to run pisg in crontab, then do 'crontab -e' as a normal user, # and insert a line like this: */10 * * * * /path/to/pisg --silent # This will make pisg run every 10 minutes, or you could do it every hour # by doing this: 0 * * * * /path/to/pisg --silent pisg-0.73/scripts/pum/0000775000076400007650000000000011705647720013343 5ustar wadewadepisg-0.73/scripts/pum/pum.pl0000774000076400007650000003061111705647720014504 0ustar wadewade#!/usr/bin/perl -w ### ### pisg user manager version 3.2 ### ### Copyleft (C) 2005 by Axel 'XTaran' Beckert ### Copyleft (C) 2005 by Torbjörn 'Azoff' Svensson ### # # This is complete reimplementation from scratch of addalias script # 2.2 by deadlock which itself was based on the original addalias # program by Doomshammer # # The purpose of this script is to let users manage themself their # info for the pisg ircstats program by mbrix. # # This program may be used, copied and distributed under the terms of # the GNU General Public License (GPL) version 2 or later. See # http://www.gnu.org/copyleft/gpl.txt or the file COPYING for the full # license text. # # Version History: # # 3.0: Initial program by XTaran # 3.1: First released version with a lot of patches by Azoff # 3.2: Action buttons instead of links since search engines follow # links and therefore deleted nicks (XTaran) # # Credits from XTaran to # + Christoph 'Myon' Berg for motivating me to rewrite addalias.pl # + #plant on IRCNet (and again Myon ;-) without which I probably # never would have used addalias.pl and therefore never felt the # urge to rewrite it from scratch. ;-) # + The Debian Project for the operating system running on my 133 MHz # IBM ThinkPad, on which I developed my parts of this piece of Open # Source Software (although I have other machines around, but I # entirely developed the script while sitting on the toilet, in bed # or in the bath tub. ;-) # + Larry for Perl # + RMS for GNU Emacs use Data::Dumper; use AppConfig qw(ARGCOUNT_ONE); use CGI qw(:standard *table); use CGI::Carp qw(fatalsToBrowser carpout); ### ### BEGIN CONFIG ### my $config_file = "pum.conf"; ### ### END CONFIG ### ### ### BEGIN INIT ### my $VERSION = '3.2'; my $title_prefix = "pisg IRC Statistics User Manager $VERSION"; my $script_uri = $ENV{SCRIPT_NAME}; my %data = (); my @attributes = qw(nick alias link sex pic bigpic ignore); param( -name => 'op', -value => 'list' ) unless defined param('op'); # print the default css if (param('op') eq 'css') { print <new({ GLOBAL => { ARGCOUNT => ARGCOUNT_ONE }}); $config->define('cgi_css', { DEFAULT => '' }); $config->define('cgi_debug', { DEFAULT => 0 }); $config->define('cgi_alias_disp', { DEFAULT => 30 }); $config->define('cgi_user_del', { DEFAULT => 0 }); $config->define('cgi_pics_prefix', { DEFAULT => '' }); $config->define('backup_enable', { DEFAULT => '1' }); $config->define('backup_dir', { DEFAULT => '/tmp' }); $config->define('backup_suffix', { DEFAULT => '%t' }); $config->define('list_buttons', { DEFAULT => 0 }); $config->define('pisg_user_config', { DEFAULT => 'users.conf' }); -e $config_file or die "Configuration file $config_file doesn't exist"; -f _ or die "Configuration file $config_file is no file"; -r _ or die "Configuration file $config_file is not readable"; $config->file($config_file); ### ### END INIT ### my $title = $title_prefix; my $css = $config->get('cgi_css'); if (param('op') eq 'show') { $title .= ": Show user '".param('nick')."'"; } elsif (param('op') eq 'edit') { $title .= ": Edit user '".param('nick')."'"; } elsif (param('op') eq 'list') { $title .= ": List all known nicknames"; } elsif (param('op') eq 'del') { $title .= ": Delete user '".param('nick')."'"; } print start_html(-title => $title, -style => { src => ($css ? $css : "$script_uri?op=css")}); print "\n" . h1($title) . "\n"; if (param('op') eq 'show') { &show_data; print _p(a({ href => $script_uri.'?op=edit&nick='.param('nick') }, "Edit this data set")); } elsif (param('op') eq 'edit') { &show_data_form; } elsif (param('op') eq 'save' or param('op') eq 'create') { &save_data; } elsif (param('op') eq 'list') { &show_nicks; } elsif (param('op') eq 'del' and $config->get('cgi_user_del')) { &del_nick; } else { print _p("Error: Unknown operation!"); } if (not (param('op') eq 'del' and not param('confirm') and $config->get('cgi_user_del'))) { print _p(a({ href => "$script_uri?op=edit" }, 'Create new nick')); print _p(a({ href => "$script_uri?op=list" }, 'List all known nicks')); print _p('Back to the '.a({ href => $script_uri }, 'pum start page')); } print hr,pre(Dumper({ map { $_ => param($_) } param() },\%data,\%ENV)) if ($config->get('cgi_debug') or param('debug')); print end_html(); ### ### functions ### # make html readable sub _table { return table(@_) . "\n"; } sub _th { return th(@_) . "\n"; } sub _Tr { return Tr(@_) . "\n"; } sub _td { return td(@_) . "\n"; } sub _start_form { return start_form(@_) . "\n"; } sub _hidden { return hidden(@_) . "\n"; } sub _submit { return submit(@_) . "\n"; } sub _reset { return reset(@_) . "\n"; } sub _end_form { return "\n"; } sub _p { return p(@_) . "\n"; } sub read_config { my ($user) = @_; my $filename = &get_user_config; open(CFG, '<', $filename) or die "Can't open pisg user configuration file '$filename' for reading: $!"; while (my $line = ) { chomp($line); next if $line =~ /^(|#.*)$/; die "Unknown pisg user configuration file syntax: '$line'" unless $line =~ m|^\s*\s*$|i; my $line_data_string = $1; my %line_data = (); while ($line_data_string =~ s/^(\w+)="([^\"]+)"\s*//) { $line_data{lc($1)} = $2; } my $nick = $line_data{nick}; die "No nickname(s) found in '$line'" unless $nick; $data{lc($nick)} = \%line_data; last if lc($user) eq lc($nick); } close(CFG); } sub write_config { my $filename = &get_user_config; if ($config->get('backup_enable')) { use File::Basename; use File::Copy; my $time = time(); my $dir = $config->get('backup_dir'); my $name = basename($filename); my $suffix = $config->get('backup_suffix'); my $newfile = "$dir/$name.$suffix"; $newfile =~ s/\%t/$time/; copy($filename, $newfile) or warn "Couldn't copy '$filename' to $newfile': $!"; } open(CFG, '>', $filename) or die "Can't open pisg user configuration file '$filename' for writing: $!"; foreach my $key (sort { lc($a) cmp lc($b) } keys %data) { my $set = $data{$key}; print CFG qq{{nick}; foreach my $attr (@attributes) { print CFG qq[ $attr="$set->{$attr}"] if $set->{$attr}; } print CFG qq{>\n}; } close(CFG); } sub get_user_config { my $filename = $config->get('pisg_user_config') or die "Can't find key user_config in section pisg in config file $config_file"; return $filename; } sub save_data { die "No nick given" unless param('nick'); die "Nick may be only changed in capitalisation" if lc(param('nick')) ne lc(param('old_nick')) and param('op') ne 'create'; my %new_data = (); foreach my $attr (@attributes) { my $value = param($attr); next unless $value; next if $attr eq 'sex' and $value eq '-'; die "No double quotes allowed in data: '$value'" if $value =~ /\"/; warn "Waka waka in data: '$value'" if $value =~ /[<>]/; $new_data{$attr} = $value; } my $nick = $new_data{nick}; die "No nick in data found" unless $nick; &read_config; die "Data for nick '".lc($nick)."' already exists" if param('op') eq 'create' and $data{lc($nick)}; $data{lc($nick)} = \%new_data; &write_config; print _p('Data successfully saved.'); &show_data; &show_data_form; } sub show_data { my $this = shift; unless ($this) { my $nick = lc(param('nick')); read_config($nick); $this = $data{$nick}; } my $pp = $config->get('cgi_pics_prefix'); print start_table; print _Tr(_th('Nickname'), _th($this->{nick})); print _Tr(_td('Alias(ses)'), _td($this->{alias})); print _Tr(_td('Link'), _td(defined($this->{link}) and $this->{link} =~ m(^http://)i ? a({ href => $this->{link}}, $this->{link}) : $this->{link} ? a({ href => "mailto:$this->{link}"}, $this->{link}) : '(unset)')); print _Tr(_td('Sex'), _td(defined $this->{sex} ? $this->{sex} eq 'm' ? 'male' : $this->{sex} eq 'f' ? 'female' : $this->{sex} eq 'b' ? 'bot' : '(unset)' : '(unset)')); print _Tr(_td('Picture'), _td($this->{pic} ? img({ src => $pp.$this->{pic}, alt => $this->{pic} }) : '(unset)')); print _Tr(_td('Big picture'), _td($this->{bigpic} ? a({href => $pp.$this->{bigpic}}, $this->{bigpic}) : '(unset)')); print _Tr(_td('Ignore'), _td($this->{ignore} ? 'True' : 'False')); print end_table; } sub show_data_form { my $nick = lc(param('nick')); read_config($nick) if $nick; my $this = $data{$nick}; my $pp = $config->get('cgi_pics_prefix'); print _start_form('GET', $script_uri); print _hidden( -name => 'op', -value => ( ($nick or param('op') eq 'create') ? 'save' : 'create' ), -override => 1); print _hidden('old_nick', $nick); print _table(_Tr(_td('Nickname'), _td(textfield('nick',$this->{nick},9))), _Tr(_td('Alias(ses)'), _td(textfield('alias',$this->{alias},30))), _Tr(_td('Link'), _td(textfield('link',$this->{link},30))), _Tr(_td('Sex'), _td(radio_group('sex',['f','m','b','-'], $this->{sex} || '-','', { f => 'female', m => 'male', b => 'bot', '-' => 'unspecified' }))), _Tr(_td('Picture'), _td(textfield('pic',$this->{pic},30))), _Tr(_td('Big picture'), _td(textfield('bigpic',$this->{bigpic},30))), _Tr(_td('Ignore'), _td(checkbox('ignore', ($this->{ignore} ? 'checked' : ''), 'y', '')))); print _submit('submit', 'Save data set'); print _reset('reset', 'Reset form'); print _end_form(); if (defined $data{lc($nick)}) { print _start_form('GET', $script_uri); print _hidden( -name => 'op', -value => 'del', -override => 1); print _hidden('nick', $nick); print _submit('submit', "Remove data for '$nick'"); print _end_form(); } } sub _get_op($$) { my $op = shift; my $nick = shift; return ($config->get('list_buttons') ? _start_form('GET'). _hidden('nick', $nick). _submit('op', $op). _end_form() : a({ href => "$script_uri?op=$op&nick=".escapeHTML($nick) }, $op) ); } sub show_nicks { read_config(); print start_table; my $i=1; my $alias_disp = $config->get('cgi_alias_disp'); foreach my $nick (sort keys %data) { my $alias = $data{$nick}{alias} || ''; $nick = $data{$nick}{nick}; if (length($alias) > $alias_disp) { $alias = substr($alias, 0, $alias_disp) . '...'; } print _Tr( _td({id => 'num'}, $i), _td(&_get_op('show', $nick)), _td(&_get_op('edit', $nick)), ($config->get('cgi_user_del') ? _td(&_get_op('del', $nick)) : '' ), _td(escapeHTML($nick.($alias ? " ($alias)" : ''))), ); $i++; } print end_table; } sub del_nick { my $nick = param('nick'); die "No nick given" unless $nick; if (param('confirm')) { &read_config; die "No such nick '$nick'." unless defined $data{lc($nick)}; delete $data{lc($nick)}; &write_config; print _p("User '$nick' successfully deleted."); } elsif (param('no')) { &show_nicks; } else { print _p("Are you sure you want to delete the user '$nick'?"); print _p(_start_form('GET'), _hidden('nick',$nick), _hidden('op','del'), _submit('confirm', 'Yes'), # Not all CGI.pm version know -onclick, so it's hardcoded here '', _end_form()); } } pisg-0.73/scripts/pum/pum.conf0000774000076400007650000000267411705647720015026 0ustar wadewade[pisg] # Defines where the user data is located. This file must be writeable # by the user the pum.pl script is running under (this user often is # called "www", "wwwdata", "apache" or similar). Also note that this # file should only contain user info, since it will be overwritten by # pum.pl. user_config = users.conf [cgi] # If commented, pum handles CSS internally. Comment it in to use an # external CSS file. Do not put the CSS file into the cgi-bin # directory where pum.pl itself is located -- because it won't work in # most installations since the cgi-bin directory is reserved for CGI # scripts only. #css = /css/pum.css # Set it to the same as ImagePath in pisg.conf. pics_prefix = /pics/ # Turn on some more debug info. Can also be triggerd by using # 'debug=1' in the query string, e.g. with # http://your.webserver/cgi-bin/pum.pl?debug=1 debug = 0 # Are users allowed to remove nicks? 1 = yes 0 = no user_del = 1 # how many chars to display in the summarylist alias_disp = 30 [backup] # Should pum.pl create a backup file each time it changes something? # Note that the user this script is running under must have permission # to write to the directory option below. enable = 0 # To which directory should the backups written to? dir = /tmp # What string should be appended to the backup file name? "%t" is # replaced by the current Unix time (that means the output of Perl's # time() function). WARNING: This can fill up your disk! suffix = %t