├── .gitignore ├── .project ├── LICENSE ├── README ├── README.md ├── db └── install.sql ├── fmsloganalyzer.ini.sample ├── includes ├── GeoIP │ ├── GeoIP.dat │ └── geoip.inc └── config.php ├── process.php └── webroot ├── OFC ├── open-flash-chart.swf └── php-ofc-library │ ├── JSON.php │ ├── README.txt │ ├── dot_base.php │ ├── json_format.php │ ├── ofc_area_base.php │ ├── ofc_area_hollow.php │ ├── ofc_area_line.php │ ├── ofc_arrow.php │ ├── ofc_bar.php │ ├── ofc_bar_3d.php │ ├── ofc_bar_base.php │ ├── ofc_bar_filled.php │ ├── ofc_bar_glass.php │ ├── ofc_bar_sketch.php │ ├── ofc_bar_stack.php │ ├── ofc_candle.php │ ├── ofc_hbar.php │ ├── ofc_line.php │ ├── ofc_line_base.php │ ├── ofc_line_dot.php │ ├── ofc_line_hollow.php │ ├── ofc_line_style.php │ ├── ofc_menu.php │ ├── ofc_pie.php │ ├── ofc_radar_axis.php │ ├── ofc_radar_axis_labels.php │ ├── ofc_radar_spoke_labels.php │ ├── ofc_scatter.php │ ├── ofc_scatter_line.php │ ├── ofc_shape.php │ ├── ofc_sugar.php │ ├── ofc_tags.php │ ├── ofc_title.php │ ├── ofc_tooltip.php │ ├── ofc_upload_image.php │ ├── ofc_x_axis.php │ ├── ofc_x_axis_label.php │ ├── ofc_x_axis_labels.php │ ├── ofc_x_legend.php │ ├── ofc_y_axis.php │ ├── ofc_y_axis_base.php │ ├── ofc_y_axis_label.php │ ├── ofc_y_axis_labels.php │ ├── ofc_y_axis_right.php │ ├── ofc_y_legend.php │ ├── open-flash-chart-object.php │ └── open-flash-chart.php ├── concurrent.php ├── css └── style.css ├── data ├── bandwidth-by-time-line.php ├── hits-by-country-bar.php ├── hits-by-country-pie.php ├── hits-by-day-bar.php ├── hits-by-month-bar.php └── peakbandwidth-by-time-line.php ├── index.php └── js └── swfobject ├── expressInstall.swf └── swfobject.js /.gitignore: -------------------------------------------------------------------------------- 1 | /nbproject/private/ 2 | nbproject/project.xml 3 | logs/access.log 4 | nbproject/project.properties 5 | fmsloganalyzer.ini 6 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | fmsloganalyzer 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.wst.validation.validationbuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.dltk.core.scriptbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.php.core.PHPNature 21 | 22 | 23 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | GNU GENERAL PUBLIC LICENSE 2 | Version 2, June 1991 3 | 4 | Copyright (C) 1989, 1991 Free Software Foundation, Inc., 5 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 6 | Everyone is permitted to copy and distribute verbatim copies 7 | of this license document, but changing it is not allowed. 8 | 9 | Preamble 10 | 11 | The licenses for most software are designed to take away your 12 | freedom to share and change it. By contrast, the GNU General Public 13 | License is intended to guarantee your freedom to share and change free 14 | software--to make sure the software is free for all its users. This 15 | General Public License applies to most of the Free Software 16 | Foundation's software and to any other program whose authors commit to 17 | using it. (Some other Free Software Foundation software is covered by 18 | the GNU Lesser General Public License instead.) You can apply it to 19 | your programs, too. 20 | 21 | When we speak of free software, we are referring to freedom, not 22 | price. Our General Public Licenses are designed to make sure that you 23 | have the freedom to distribute copies of free software (and charge for 24 | this service if you wish), that you receive source code or can get it 25 | if you want it, that you can change the software or use pieces of it 26 | in new free programs; and that you know you can do these things. 27 | 28 | To protect your rights, we need to make restrictions that forbid 29 | anyone to deny you these rights or to ask you to surrender the rights. 30 | These restrictions translate to certain responsibilities for you if you 31 | distribute copies of the software, or if you modify it. 32 | 33 | For example, if you distribute copies of such a program, whether 34 | gratis or for a fee, you must give the recipients all the rights that 35 | you have. You must make sure that they, too, receive or can get the 36 | source code. And you must show them these terms so they know their 37 | rights. 38 | 39 | We protect your rights with two steps: (1) copyright the software, and 40 | (2) offer you this license which gives you legal permission to copy, 41 | distribute and/or modify the software. 42 | 43 | Also, for each author's protection and ours, we want to make certain 44 | that everyone understands that there is no warranty for this free 45 | software. If the software is modified by someone else and passed on, we 46 | want its recipients to know that what they have is not the original, so 47 | that any problems introduced by others will not reflect on the original 48 | authors' reputations. 49 | 50 | Finally, any free program is threatened constantly by software 51 | patents. We wish to avoid the danger that redistributors of a free 52 | program will individually obtain patent licenses, in effect making the 53 | program proprietary. To prevent this, we have made it clear that any 54 | patent must be licensed for everyone's free use or not licensed at all. 55 | 56 | The precise terms and conditions for copying, distribution and 57 | modification follow. 58 | 59 | GNU GENERAL PUBLIC LICENSE 60 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 61 | 62 | 0. This License applies to any program or other work which contains 63 | a notice placed by the copyright holder saying it may be distributed 64 | under the terms of this General Public License. The "Program", below, 65 | refers to any such program or work, and a "work based on the Program" 66 | means either the Program or any derivative work under copyright law: 67 | that is to say, a work containing the Program or a portion of it, 68 | either verbatim or with modifications and/or translated into another 69 | language. (Hereinafter, translation is included without limitation in 70 | the term "modification".) Each licensee is addressed as "you". 71 | 72 | Activities other than copying, distribution and modification are not 73 | covered by this License; they are outside its scope. The act of 74 | running the Program is not restricted, and the output from the Program 75 | is covered only if its contents constitute a work based on the 76 | Program (independent of having been made by running the Program). 77 | Whether that is true depends on what the Program does. 78 | 79 | 1. You may copy and distribute verbatim copies of the Program's 80 | source code as you receive it, in any medium, provided that you 81 | conspicuously and appropriately publish on each copy an appropriate 82 | copyright notice and disclaimer of warranty; keep intact all the 83 | notices that refer to this License and to the absence of any warranty; 84 | and give any other recipients of the Program a copy of this License 85 | along with the Program. 86 | 87 | You may charge a fee for the physical act of transferring a copy, and 88 | you may at your option offer warranty protection in exchange for a fee. 89 | 90 | 2. You may modify your copy or copies of the Program or any portion 91 | of it, thus forming a work based on the Program, and copy and 92 | distribute such modifications or work under the terms of Section 1 93 | above, provided that you also meet all of these conditions: 94 | 95 | a) You must cause the modified files to carry prominent notices 96 | stating that you changed the files and the date of any change. 97 | 98 | b) You must cause any work that you distribute or publish, that in 99 | whole or in part contains or is derived from the Program or any 100 | part thereof, to be licensed as a whole at no charge to all third 101 | parties under the terms of this License. 102 | 103 | c) If the modified program normally reads commands interactively 104 | when run, you must cause it, when started running for such 105 | interactive use in the most ordinary way, to print or display an 106 | announcement including an appropriate copyright notice and a 107 | notice that there is no warranty (or else, saying that you provide 108 | a warranty) and that users may redistribute the program under 109 | these conditions, and telling the user how to view a copy of this 110 | License. (Exception: if the Program itself is interactive but 111 | does not normally print such an announcement, your work based on 112 | the Program is not required to print an announcement.) 113 | 114 | These requirements apply to the modified work as a whole. If 115 | identifiable sections of that work are not derived from the Program, 116 | and can be reasonably considered independent and separate works in 117 | themselves, then this License, and its terms, do not apply to those 118 | sections when you distribute them as separate works. But when you 119 | distribute the same sections as part of a whole which is a work based 120 | on the Program, the distribution of the whole must be on the terms of 121 | this License, whose permissions for other licensees extend to the 122 | entire whole, and thus to each and every part regardless of who wrote it. 123 | 124 | Thus, it is not the intent of this section to claim rights or contest 125 | your rights to work written entirely by you; rather, the intent is to 126 | exercise the right to control the distribution of derivative or 127 | collective works based on the Program. 128 | 129 | In addition, mere aggregation of another work not based on the Program 130 | with the Program (or with a work based on the Program) on a volume of 131 | a storage or distribution medium does not bring the other work under 132 | the scope of this License. 133 | 134 | 3. You may copy and distribute the Program (or a work based on it, 135 | under Section 2) in object code or executable form under the terms of 136 | Sections 1 and 2 above provided that you also do one of the following: 137 | 138 | a) Accompany it with the complete corresponding machine-readable 139 | source code, which must be distributed under the terms of Sections 140 | 1 and 2 above on a medium customarily used for software interchange; or, 141 | 142 | b) Accompany it with a written offer, valid for at least three 143 | years, to give any third party, for a charge no more than your 144 | cost of physically performing source distribution, a complete 145 | machine-readable copy of the corresponding source code, to be 146 | distributed under the terms of Sections 1 and 2 above on a medium 147 | customarily used for software interchange; or, 148 | 149 | c) Accompany it with the information you received as to the offer 150 | to distribute corresponding source code. (This alternative is 151 | allowed only for noncommercial distribution and only if you 152 | received the program in object code or executable form with such 153 | an offer, in accord with Subsection b above.) 154 | 155 | The source code for a work means the preferred form of the work for 156 | making modifications to it. For an executable work, complete source 157 | code means all the source code for all modules it contains, plus any 158 | associated interface definition files, plus the scripts used to 159 | control compilation and installation of the executable. However, as a 160 | special exception, the source code distributed need not include 161 | anything that is normally distributed (in either source or binary 162 | form) with the major components (compiler, kernel, and so on) of the 163 | operating system on which the executable runs, unless that component 164 | itself accompanies the executable. 165 | 166 | If distribution of executable or object code is made by offering 167 | access to copy from a designated place, then offering equivalent 168 | access to copy the source code from the same place counts as 169 | distribution of the source code, even though third parties are not 170 | compelled to copy the source along with the object code. 171 | 172 | 4. You may not copy, modify, sublicense, or distribute the Program 173 | except as expressly provided under this License. Any attempt 174 | otherwise to copy, modify, sublicense or distribute the Program is 175 | void, and will automatically terminate your rights under this License. 176 | However, parties who have received copies, or rights, from you under 177 | this License will not have their licenses terminated so long as such 178 | parties remain in full compliance. 179 | 180 | 5. You are not required to accept this License, since you have not 181 | signed it. However, nothing else grants you permission to modify or 182 | distribute the Program or its derivative works. These actions are 183 | prohibited by law if you do not accept this License. Therefore, by 184 | modifying or distributing the Program (or any work based on the 185 | Program), you indicate your acceptance of this License to do so, and 186 | all its terms and conditions for copying, distributing or modifying 187 | the Program or works based on it. 188 | 189 | 6. Each time you redistribute the Program (or any work based on the 190 | Program), the recipient automatically receives a license from the 191 | original licensor to copy, distribute or modify the Program subject to 192 | these terms and conditions. You may not impose any further 193 | restrictions on the recipients' exercise of the rights granted herein. 194 | You are not responsible for enforcing compliance by third parties to 195 | this License. 196 | 197 | 7. If, as a consequence of a court judgment or allegation of patent 198 | infringement or for any other reason (not limited to patent issues), 199 | conditions are imposed on you (whether by court order, agreement or 200 | otherwise) that contradict the conditions of this License, they do not 201 | excuse you from the conditions of this License. If you cannot 202 | distribute so as to satisfy simultaneously your obligations under this 203 | License and any other pertinent obligations, then as a consequence you 204 | may not distribute the Program at all. For example, if a patent 205 | license would not permit royalty-free redistribution of the Program by 206 | all those who receive copies directly or indirectly through you, then 207 | the only way you could satisfy both it and this License would be to 208 | refrain entirely from distribution of the Program. 209 | 210 | If any portion of this section is held invalid or unenforceable under 211 | any particular circumstance, the balance of the section is intended to 212 | apply and the section as a whole is intended to apply in other 213 | circumstances. 214 | 215 | It is not the purpose of this section to induce you to infringe any 216 | patents or other property right claims or to contest validity of any 217 | such claims; this section has the sole purpose of protecting the 218 | integrity of the free software distribution system, which is 219 | implemented by public license practices. Many people have made 220 | generous contributions to the wide range of software distributed 221 | through that system in reliance on consistent application of that 222 | system; it is up to the author/donor to decide if he or she is willing 223 | to distribute software through any other system and a licensee cannot 224 | impose that choice. 225 | 226 | This section is intended to make thoroughly clear what is believed to 227 | be a consequence of the rest of this License. 228 | 229 | 8. If the distribution and/or use of the Program is restricted in 230 | certain countries either by patents or by copyrighted interfaces, the 231 | original copyright holder who places the Program under this License 232 | may add an explicit geographical distribution limitation excluding 233 | those countries, so that distribution is permitted only in or among 234 | countries not thus excluded. In such case, this License incorporates 235 | the limitation as if written in the body of this License. 236 | 237 | 9. The Free Software Foundation may publish revised and/or new versions 238 | of the General Public License from time to time. Such new versions will 239 | be similar in spirit to the present version, but may differ in detail to 240 | address new problems or concerns. 241 | 242 | Each version is given a distinguishing version number. If the Program 243 | specifies a version number of this License which applies to it and "any 244 | later version", you have the option of following the terms and conditions 245 | either of that version or of any later version published by the Free 246 | Software Foundation. If the Program does not specify a version number of 247 | this License, you may choose any version ever published by the Free Software 248 | Foundation. 249 | 250 | 10. If you wish to incorporate parts of the Program into other free 251 | programs whose distribution conditions are different, write to the author 252 | to ask for permission. For software which is copyrighted by the Free 253 | Software Foundation, write to the Free Software Foundation; we sometimes 254 | make exceptions for this. Our decision will be guided by the two goals 255 | of preserving the free status of all derivatives of our free software and 256 | of promoting the sharing and reuse of software generally. 257 | 258 | NO WARRANTY 259 | 260 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 261 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN 262 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES 263 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED 264 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 265 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS 266 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE 267 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, 268 | REPAIR OR CORRECTION. 269 | 270 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 271 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR 272 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, 273 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING 274 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED 275 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY 276 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER 277 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE 278 | POSSIBILITY OF SUCH DAMAGES. 279 | 280 | END OF TERMS AND CONDITIONS 281 | 282 | How to Apply These Terms to Your New Programs 283 | 284 | If you develop a new program, and you want it to be of the greatest 285 | possible use to the public, the best way to achieve this is to make it 286 | free software which everyone can redistribute and change under these terms. 287 | 288 | To do so, attach the following notices to the program. It is safest 289 | to attach them to the start of each source file to most effectively 290 | convey the exclusion of warranty; and each file should have at least 291 | the "copyright" line and a pointer to where the full notice is found. 292 | 293 | 294 | Copyright (C) 295 | 296 | This program is free software; you can redistribute it and/or modify 297 | it under the terms of the GNU General Public License as published by 298 | the Free Software Foundation; either version 2 of the License, or 299 | (at your option) any later version. 300 | 301 | This program is distributed in the hope that it will be useful, 302 | but WITHOUT ANY WARRANTY; without even the implied warranty of 303 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 304 | GNU General Public License for more details. 305 | 306 | You should have received a copy of the GNU General Public License along 307 | with this program; if not, write to the Free Software Foundation, Inc., 308 | 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 309 | 310 | Also add information on how to contact you by electronic and paper mail. 311 | 312 | If the program is interactive, make it output a short notice like this 313 | when it starts in an interactive mode: 314 | 315 | Gnomovision version 69, Copyright (C) year name of author 316 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. 317 | This is free software, and you are welcome to redistribute it 318 | under certain conditions; type `show c' for details. 319 | 320 | The hypothetical commands `show w' and `show c' should show the appropriate 321 | parts of the General Public License. Of course, the commands you use may 322 | be called something other than `show w' and `show c'; they could even be 323 | mouse-clicks or menu items--whatever suits your program. 324 | 325 | You should also get your employer (if you work as a programmer) or your 326 | school, if any, to sign a "copyright disclaimer" for the program, if 327 | necessary. Here is a sample; alter the names: 328 | 329 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program 330 | `Gnomovision' (which makes passes at compilers) written by James Hacker. 331 | 332 | , 1 April 1989 333 | Ty Coon, President of Vice 334 | 335 | This General Public License does not permit incorporating your program into 336 | proprietary programs. If your program is a subroutine library, you may 337 | consider it more useful to permit linking proprietary applications with the 338 | library. If this is what you want to do, use the GNU Lesser General 339 | Public License instead of this License. 340 | -------------------------------------------------------------------------------- /README: -------------------------------------------------------------------------------- 1 | $Id: README 3 2009-09-15 22:00:39Z bvamos $ 2 | 3 | (C) 2009 Balazs Vamos 4 | 5 | FMS Log Analyzer is distributed under the terms of GNU GPL 6 | 7 | WELCOME 8 | 9 | FMS Log Analyzer is an Adobe Flash Media Server Access log analyzer written 10 | in PHP and using MySQL as a backend database store. Supported log file format 11 | is the access log format of Adobe Flash Media Streaming Server. 12 | 13 | PREREQUISITES 14 | 15 | - A web server with PHP >= 4.3 16 | - Access log files of FMS 17 | - A MySQL database server >= 3.23.52 or any production release of 4.x or 5.x 18 | - Web browser 19 | 20 | RELEASE NOTES 21 | 22 | Latest release: 1.0 23 | Release date: 2009-09-15 24 | 25 | New features: 26 | - Initial release 27 | 28 | INSTALLATION 29 | 30 | Copy all the files into a directory and set up an alias or virtual host with 31 | webroot as the Document root. 32 | Create a MySQL database and create fmslog table. SQL can be found in 33 | db/install.sql. 34 | 35 | USE 36 | 37 | Before starting FMS Log Analyzer for the first time, you should review the 38 | fmsloganalyzer.ini.sample file, rename to fmsloganalyzer.ini and adjust it 39 | as needed for your installation. 40 | Run process.php to generate statistic data from log files. 41 | You can see statistics by pointing your web browser to: 42 | http:///index.php 43 | When you load the FMS Log Analyzer home page, you will see a couple of 44 | valued reports from your FMS access logs. 45 | 46 | COMMENTS 47 | 48 | Please let me know what you think! If you have questions or comments please 49 | email me at bvamos@fmsloganalyzer.com. 50 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # nginx-hls-analyzer (Analyze LiveStream Access) 2 | 3 | nginx-hls-analyzer is a nginx (with compiled nginx-rtmp-module) HLS LiveStream access log analyzer written in PHP and using MySQL as a backend database store. Supported log file format is the access log format of nginx with the following settings (http-area-settings). 4 | 5 | ```nginx 6 | log_format json_combined escape=json '{ "time_local": "$time_local", ' 7 | '"remote_addr": "$remote_addr", ' 8 | '"connection": "$connection", ' 9 | '"remote_user": "$remote_user", ' 10 | '"request": "$request", ' 11 | '"status": "$status", ' 12 | '"bytes_sent": "$bytes_sent", ' 13 | '"request_time": "$request_time", ' 14 | '"http_referrer": "$http_referer", ' 15 | '"http_user_agent": "$http_user_agent" }'; 16 | 17 | access_log logs/access.log json_combined; 18 | ``` 19 | 20 | ## PREREQUISITES 21 | 22 | - A web server with PHP >= 5 23 | - Access log files with HLS access of nginx with json log file format 24 | - A MySQL/MariaDB database server >= 3.23.52 or any production release of 4.x or 5.x 25 | - Web browser 26 | 27 | ## Installation 28 | 29 | - Copy all the files into a directory and set up an alias or virtual host with webroot as the Document root. 30 | - Create a MySQL database and create necessary tables. SQL can be found in db/install.sql. 31 | 32 | ## Usage 33 | 34 | - Before starting FMS Log Analyzer for the first time, you should review the fmsloganalyzer.ini.sample file, rename to fmsloganalyzer.ini and adjust it as needed for your installation. 35 | - Run process.php to generate statistic data from log files. 36 | - You can see statistics by pointing your web browser to: 37 | - http:///index.php 38 | - When you load the FMS Log Analyzer home page, you will see a couple of valued reports from your FMS access logs. -------------------------------------------------------------------------------- /db/install.sql: -------------------------------------------------------------------------------- 1 | SET SQL_MODE = "NO_AUTO_VALUE_ON_ZERO"; 2 | SET AUTOCOMMIT = 0; 3 | START TRANSACTION; 4 | SET time_zone = "+00:00"; 5 | 6 | 7 | /*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; 8 | /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; 9 | /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; 10 | /*!40101 SET NAMES utf8mb4 */; 11 | 12 | -- 13 | -- Datenbank: `nginxhlslog` 14 | -- 15 | 16 | -- -------------------------------------------------------- 17 | 18 | -- 19 | -- Tabellenstruktur für Tabelle `connections` 20 | -- 21 | 22 | CREATE TABLE `connections` ( 23 | `id` int(11) NOT NULL, 24 | `c-client-id` varchar(100) NOT NULL, 25 | `c-ip` varchar(30) NOT NULL, 26 | `c-agent` TEXT NOT NULL, 27 | `c-ip-country` varchar(30) NOT NULL, 28 | `streamname` varchar(100) NOT NULL, 29 | `timestamp-start` datetime NOT NULL, 30 | `timestamp-end` datetime NOT NULL, 31 | `bytes` int(11) NOT NULL, 32 | `duration` int(11) NOT NULL 33 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 34 | 35 | -- -------------------------------------------------------- 36 | 37 | -- 38 | -- Tabellenstruktur für Tabelle `last_update` 39 | -- 40 | 41 | CREATE TABLE `last_update` ( 42 | `time` datetime NOT NULL 43 | ) ENGINE=InnoDB DEFAULT CHARSET=latin1; 44 | 45 | -- 46 | -- Daten für Tabelle `last_update` 47 | -- 48 | 49 | INSERT INTO `last_update` (`time`) VALUES 50 | ('1970-01-01 12:00:00'); 51 | 52 | -- -------------------------------------------------------- 53 | 54 | -- 55 | -- Tabellenstruktur für Tabelle `log` 56 | -- 57 | 58 | CREATE TABLE `log` ( 59 | `id` int(11) NOT NULL, 60 | `c-client-id` varchar(100) DEFAULT NULL, 61 | `c-client-id-conn` varchar(100) NOT NULL, 62 | `c-ip` varchar(30) DEFAULT NULL, 63 | `c-agent` TEXT NOT NULL, 64 | `c-ip-country` varchar(30) DEFAULT NULL, 65 | `streamname` varchar(100) DEFAULT NULL, 66 | `streamquality` varchar(100) DEFAULT NULL, 67 | `connection-id` varchar(100) NOT NULL, 68 | `timestamp` datetime DEFAULT NULL, 69 | `bytes` int(11) DEFAULT NULL, 70 | `evaluated` tinyint(4) NOT NULL DEFAULT '0' 71 | ) ENGINE=MyISAM DEFAULT CHARSET=latin1; 72 | 73 | -- 74 | -- Indizes der exportierten Tabellen 75 | -- 76 | 77 | -- 78 | -- Indizes für die Tabelle `connections` 79 | -- 80 | ALTER TABLE `connections` 81 | ADD PRIMARY KEY (`id`), 82 | ADD KEY `c-client-id` (`c-client-id`); 83 | 84 | -- 85 | -- Indizes für die Tabelle `log` 86 | -- 87 | ALTER TABLE `log` 88 | ADD PRIMARY KEY (`id`), 89 | ADD KEY `timestamp` (`timestamp`); 90 | 91 | -- 92 | -- AUTO_INCREMENT für exportierte Tabellen 93 | -- 94 | 95 | -- 96 | -- AUTO_INCREMENT für Tabelle `connections` 97 | -- 98 | ALTER TABLE `connections` 99 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=7; 100 | 101 | -- 102 | -- AUTO_INCREMENT für Tabelle `log` 103 | -- 104 | ALTER TABLE `log` 105 | MODIFY `id` int(11) NOT NULL AUTO_INCREMENT, AUTO_INCREMENT=3023; 106 | COMMIT; 107 | 108 | /*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; 109 | /*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; 110 | /*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; 111 | -------------------------------------------------------------------------------- /fmsloganalyzer.ini.sample: -------------------------------------------------------------------------------- 1 | [Common] 2 | LogDirectory = c:\temp\logs 3 | Sitename = Your Site name 4 | DirectorySeparator = \\ 5 | 6 | [Database] 7 | Username = user 8 | Password = pass 9 | Server = localhost 10 | Database = fmslog 11 | 12 | [Filter] 13 | ;Virtualhost = 14 | -------------------------------------------------------------------------------- /includes/GeoIP/GeoIP.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openHPI/nginx-hls-analyzer/3bdcba05b6a8fd25f386f77c4da2f74506164ccb/includes/GeoIP/GeoIP.dat -------------------------------------------------------------------------------- /includes/GeoIP/geoip.inc: -------------------------------------------------------------------------------- 1 | 0, "AP" => 1, "EU" => 2, "AD" => 3, "AE" => 4, "AF" => 5, 66 | "AG" => 6, "AI" => 7, "AL" => 8, "AM" => 9, "AN" => 10, "AO" => 11, 67 | "AQ" => 12, "AR" => 13, "AS" => 14, "AT" => 15, "AU" => 16, "AW" => 17, 68 | "AZ" => 18, "BA" => 19, "BB" => 20, "BD" => 21, "BE" => 22, "BF" => 23, 69 | "BG" => 24, "BH" => 25, "BI" => 26, "BJ" => 27, "BM" => 28, "BN" => 29, 70 | "BO" => 30, "BR" => 31, "BS" => 32, "BT" => 33, "BV" => 34, "BW" => 35, 71 | "BY" => 36, "BZ" => 37, "CA" => 38, "CC" => 39, "CD" => 40, "CF" => 41, 72 | "CG" => 42, "CH" => 43, "CI" => 44, "CK" => 45, "CL" => 46, "CM" => 47, 73 | "CN" => 48, "CO" => 49, "CR" => 50, "CU" => 51, "CV" => 52, "CX" => 53, 74 | "CY" => 54, "CZ" => 55, "DE" => 56, "DJ" => 57, "DK" => 58, "DM" => 59, 75 | "DO" => 60, "DZ" => 61, "EC" => 62, "EE" => 63, "EG" => 64, "EH" => 65, 76 | "ER" => 66, "ES" => 67, "ET" => 68, "FI" => 69, "FJ" => 70, "FK" => 71, 77 | "FM" => 72, "FO" => 73, "FR" => 74, "FX" => 75, "GA" => 76, "GB" => 77, 78 | "GD" => 78, "GE" => 79, "GF" => 80, "GH" => 81, "GI" => 82, "GL" => 83, 79 | "GM" => 84, "GN" => 85, "GP" => 86, "GQ" => 87, "GR" => 88, "GS" => 89, 80 | "GT" => 90, "GU" => 91, "GW" => 92, "GY" => 93, "HK" => 94, "HM" => 95, 81 | "HN" => 96, "HR" => 97, "HT" => 98, "HU" => 99, "ID" => 100, "IE" => 101, 82 | "IL" => 102, "IN" => 103, "IO" => 104, "IQ" => 105, "IR" => 106, "IS" => 107, 83 | "IT" => 108, "JM" => 109, "JO" => 110, "JP" => 111, "KE" => 112, "KG" => 113, 84 | "KH" => 114, "KI" => 115, "KM" => 116, "KN" => 117, "KP" => 118, "KR" => 119, 85 | "KW" => 120, "KY" => 121, "KZ" => 122, "LA" => 123, "LB" => 124, "LC" => 125, 86 | "LI" => 126, "LK" => 127, "LR" => 128, "LS" => 129, "LT" => 130, "LU" => 131, 87 | "LV" => 132, "LY" => 133, "MA" => 134, "MC" => 135, "MD" => 136, "MG" => 137, 88 | "MH" => 138, "MK" => 139, "ML" => 140, "MM" => 141, "MN" => 142, "MO" => 143, 89 | "MP" => 144, "MQ" => 145, "MR" => 146, "MS" => 147, "MT" => 148, "MU" => 149, 90 | "MV" => 150, "MW" => 151, "MX" => 152, "MY" => 153, "MZ" => 154, "NA" => 155, 91 | "NC" => 156, "NE" => 157, "NF" => 158, "NG" => 159, "NI" => 160, "NL" => 161, 92 | "NO" => 162, "NP" => 163, "NR" => 164, "NU" => 165, "NZ" => 166, "OM" => 167, 93 | "PA" => 168, "PE" => 169, "PF" => 170, "PG" => 171, "PH" => 172, "PK" => 173, 94 | "PL" => 174, "PM" => 175, "PN" => 176, "PR" => 177, "PS" => 178, "PT" => 179, 95 | "PW" => 180, "PY" => 181, "QA" => 182, "RE" => 183, "RO" => 184, "RU" => 185, 96 | "RW" => 186, "SA" => 187, "SB" => 188, "SC" => 189, "SD" => 190, "SE" => 191, 97 | "SG" => 192, "SH" => 193, "SI" => 194, "SJ" => 195, "SK" => 196, "SL" => 197, 98 | "SM" => 198, "SN" => 199, "SO" => 200, "SR" => 201, "ST" => 202, "SV" => 203, 99 | "SY" => 204, "SZ" => 205, "TC" => 206, "TD" => 207, "TF" => 208, "TG" => 209, 100 | "TH" => 210, "TJ" => 211, "TK" => 212, "TM" => 213, "TN" => 214, "TO" => 215, 101 | "TL" => 216, "TR" => 217, "TT" => 218, "TV" => 219, "TW" => 220, "TZ" => 221, 102 | "UA" => 222, "UG" => 223, "UM" => 224, "US" => 225, "UY" => 226, "UZ" => 227, 103 | "VA" => 228, "VC" => 229, "VE" => 230, "VG" => 231, "VI" => 232, "VN" => 233, 104 | "VU" => 234, "WF" => 235, "WS" => 236, "YE" => 237, "YT" => 238, "RS" => 239, 105 | "ZA" => 240, "ZM" => 241, "ME" => 242, "ZW" => 243, "A1" => 244, "A2" => 245, 106 | "O1" => 246, "AX" => 247, "GG" => 248, "IM" => 249, "JE" => 250, "BL" => 251, 107 | "MF" => 252 108 | ); 109 | var $GEOIP_COUNTRY_CODES = array( 110 | "", "AP", "EU", "AD", "AE", "AF", "AG", "AI", "AL", "AM", "AN", "AO", "AQ", 111 | "AR", "AS", "AT", "AU", "AW", "AZ", "BA", "BB", "BD", "BE", "BF", "BG", "BH", 112 | "BI", "BJ", "BM", "BN", "BO", "BR", "BS", "BT", "BV", "BW", "BY", "BZ", "CA", 113 | "CC", "CD", "CF", "CG", "CH", "CI", "CK", "CL", "CM", "CN", "CO", "CR", "CU", 114 | "CV", "CX", "CY", "CZ", "DE", "DJ", "DK", "DM", "DO", "DZ", "EC", "EE", "EG", 115 | "EH", "ER", "ES", "ET", "FI", "FJ", "FK", "FM", "FO", "FR", "FX", "GA", "GB", 116 | "GD", "GE", "GF", "GH", "GI", "GL", "GM", "GN", "GP", "GQ", "GR", "GS", "GT", 117 | "GU", "GW", "GY", "HK", "HM", "HN", "HR", "HT", "HU", "ID", "IE", "IL", "IN", 118 | "IO", "IQ", "IR", "IS", "IT", "JM", "JO", "JP", "KE", "KG", "KH", "KI", "KM", 119 | "KN", "KP", "KR", "KW", "KY", "KZ", "LA", "LB", "LC", "LI", "LK", "LR", "LS", 120 | "LT", "LU", "LV", "LY", "MA", "MC", "MD", "MG", "MH", "MK", "ML", "MM", "MN", 121 | "MO", "MP", "MQ", "MR", "MS", "MT", "MU", "MV", "MW", "MX", "MY", "MZ", "NA", 122 | "NC", "NE", "NF", "NG", "NI", "NL", "NO", "NP", "NR", "NU", "NZ", "OM", "PA", 123 | "PE", "PF", "PG", "PH", "PK", "PL", "PM", "PN", "PR", "PS", "PT", "PW", "PY", 124 | "QA", "RE", "RO", "RU", "RW", "SA", "SB", "SC", "SD", "SE", "SG", "SH", "SI", 125 | "SJ", "SK", "SL", "SM", "SN", "SO", "SR", "ST", "SV", "SY", "SZ", "TC", "TD", 126 | "TF", "TG", "TH", "TJ", "TK", "TM", "TN", "TO", "TL", "TR", "TT", "TV", "TW", 127 | "TZ", "UA", "UG", "UM", "US", "UY", "UZ", "VA", "VC", "VE", "VG", "VI", "VN", 128 | "VU", "WF", "WS", "YE", "YT", "RS", "ZA", "ZM", "ME", "ZW", "A1", "A2", "O1", 129 | "AX", "GG", "IM", "JE", "BL", "MF" 130 | ); 131 | var $GEOIP_COUNTRY_CODES3 = array( 132 | "","AP","EU","AND","ARE","AFG","ATG","AIA","ALB","ARM","ANT","AGO","AQ","ARG", 133 | "ASM","AUT","AUS","ABW","AZE","BIH","BRB","BGD","BEL","BFA","BGR","BHR","BDI", 134 | "BEN","BMU","BRN","BOL","BRA","BHS","BTN","BV","BWA","BLR","BLZ","CAN","CC", 135 | "COD","CAF","COG","CHE","CIV","COK","CHL","CMR","CHN","COL","CRI","CUB","CPV", 136 | "CX","CYP","CZE","DEU","DJI","DNK","DMA","DOM","DZA","ECU","EST","EGY","ESH", 137 | "ERI","ESP","ETH","FIN","FJI","FLK","FSM","FRO","FRA","FX","GAB","GBR","GRD", 138 | "GEO","GUF","GHA","GIB","GRL","GMB","GIN","GLP","GNQ","GRC","GS","GTM","GUM", 139 | "GNB","GUY","HKG","HM","HND","HRV","HTI","HUN","IDN","IRL","ISR","IND","IO", 140 | "IRQ","IRN","ISL","ITA","JAM","JOR","JPN","KEN","KGZ","KHM","KIR","COM","KNA", 141 | "PRK","KOR","KWT","CYM","KAZ","LAO","LBN","LCA","LIE","LKA","LBR","LSO","LTU", 142 | "LUX","LVA","LBY","MAR","MCO","MDA","MDG","MHL","MKD","MLI","MMR","MNG","MAC", 143 | "MNP","MTQ","MRT","MSR","MLT","MUS","MDV","MWI","MEX","MYS","MOZ","NAM","NCL", 144 | "NER","NFK","NGA","NIC","NLD","NOR","NPL","NRU","NIU","NZL","OMN","PAN","PER", 145 | "PYF","PNG","PHL","PAK","POL","SPM","PCN","PRI","PSE","PRT","PLW","PRY","QAT", 146 | "REU","ROU","RUS","RWA","SAU","SLB","SYC","SDN","SWE","SGP","SHN","SVN","SJM", 147 | "SVK","SLE","SMR","SEN","SOM","SUR","STP","SLV","SYR","SWZ","TCA","TCD","TF", 148 | "TGO","THA","TJK","TKL","TLS","TKM","TUN","TON","TUR","TTO","TUV","TWN","TZA", 149 | "UKR","UGA","UM","USA","URY","UZB","VAT","VCT","VEN","VGB","VIR","VNM","VUT", 150 | "WLF","WSM","YEM","YT","SRB","ZAF","ZMB","MNE","ZWE","A1","A2","O1", 151 | "ALA","GGY","IMN","JEY","BLM","MAF" 152 | ); 153 | var $GEOIP_COUNTRY_NAMES = array( 154 | "", "Asia/Pacific Region", "Europe", "Andorra", "United Arab Emirates", 155 | "Afghanistan", "Antigua and Barbuda", "Anguilla", "Albania", "Armenia", 156 | "Netherlands Antilles", "Angola", "Antarctica", "Argentina", "American Samoa", 157 | "Austria", "Australia", "Aruba", "Azerbaijan", "Bosnia and Herzegovina", 158 | "Barbados", "Bangladesh", "Belgium", "Burkina Faso", "Bulgaria", "Bahrain", 159 | "Burundi", "Benin", "Bermuda", "Brunei Darussalam", "Bolivia", "Brazil", 160 | "Bahamas", "Bhutan", "Bouvet Island", "Botswana", "Belarus", "Belize", 161 | "Canada", "Cocos (Keeling) Islands", "Congo, The Democratic Republic of the", 162 | "Central African Republic", "Congo", "Switzerland", "Cote D'Ivoire", "Cook Islands", 163 | "Chile", "Cameroon", "China", "Colombia", "Costa Rica", "Cuba", "Cape Verde", 164 | "Christmas Island", "Cyprus", "Czech Republic", "Germany", "Djibouti", 165 | "Denmark", "Dominica", "Dominican Republic", "Algeria", "Ecuador", "Estonia", 166 | "Egypt", "Western Sahara", "Eritrea", "Spain", "Ethiopia", "Finland", "Fiji", 167 | "Falkland Islands (Malvinas)", "Micronesia, Federated States of", "Faroe Islands", 168 | "France", "France, Metropolitan", "Gabon", "United Kingdom", 169 | "Grenada", "Georgia", "French Guiana", "Ghana", "Gibraltar", "Greenland", 170 | "Gambia", "Guinea", "Guadeloupe", "Equatorial Guinea", "Greece", "South Georgia and the South Sandwich Islands", 171 | "Guatemala", "Guam", "Guinea-Bissau", 172 | "Guyana", "Hong Kong", "Heard Island and McDonald Islands", "Honduras", 173 | "Croatia", "Haiti", "Hungary", "Indonesia", "Ireland", "Israel", "India", 174 | "British Indian Ocean Territory", "Iraq", "Iran, Islamic Republic of", 175 | "Iceland", "Italy", "Jamaica", "Jordan", "Japan", "Kenya", "Kyrgyzstan", 176 | "Cambodia", "Kiribati", "Comoros", "Saint Kitts and Nevis", "Korea, Democratic People's Republic of", 177 | "Korea, Republic of", "Kuwait", "Cayman Islands", 178 | "Kazakhstan", "Lao People's Democratic Republic", "Lebanon", "Saint Lucia", 179 | "Liechtenstein", "Sri Lanka", "Liberia", "Lesotho", "Lithuania", "Luxembourg", 180 | "Latvia", "Libyan Arab Jamahiriya", "Morocco", "Monaco", "Moldova, Republic of", 181 | "Madagascar", "Marshall Islands", "Macedonia", 182 | "Mali", "Myanmar", "Mongolia", "Macau", "Northern Mariana Islands", 183 | "Martinique", "Mauritania", "Montserrat", "Malta", "Mauritius", "Maldives", 184 | "Malawi", "Mexico", "Malaysia", "Mozambique", "Namibia", "New Caledonia", 185 | "Niger", "Norfolk Island", "Nigeria", "Nicaragua", "Netherlands", "Norway", 186 | "Nepal", "Nauru", "Niue", "New Zealand", "Oman", "Panama", "Peru", "French Polynesia", 187 | "Papua New Guinea", "Philippines", "Pakistan", "Poland", "Saint Pierre and Miquelon", 188 | "Pitcairn Islands", "Puerto Rico", "Palestinian Territory", 189 | "Portugal", "Palau", "Paraguay", "Qatar", "Reunion", "Romania", 190 | "Russian Federation", "Rwanda", "Saudi Arabia", "Solomon Islands", 191 | "Seychelles", "Sudan", "Sweden", "Singapore", "Saint Helena", "Slovenia", 192 | "Svalbard and Jan Mayen", "Slovakia", "Sierra Leone", "San Marino", "Senegal", 193 | "Somalia", "Suriname", "Sao Tome and Principe", "El Salvador", "Syrian Arab Republic", 194 | "Swaziland", "Turks and Caicos Islands", "Chad", "French Southern Territories", 195 | "Togo", "Thailand", "Tajikistan", "Tokelau", "Turkmenistan", 196 | "Tunisia", "Tonga", "Timor-Leste", "Turkey", "Trinidad and Tobago", "Tuvalu", 197 | "Taiwan", "Tanzania, United Republic of", "Ukraine", 198 | "Uganda", "United States Minor Outlying Islands", "United States", "Uruguay", 199 | "Uzbekistan", "Holy See (Vatican City State)", "Saint Vincent and the Grenadines", 200 | "Venezuela", "Virgin Islands, British", "Virgin Islands, U.S.", 201 | "Vietnam", "Vanuatu", "Wallis and Futuna", "Samoa", "Yemen", "Mayotte", 202 | "Serbia", "South Africa", "Zambia", "Montenegro", "Zimbabwe", 203 | "Anonymous Proxy","Satellite Provider","Other", 204 | "Aland Islands","Guernsey","Isle of Man","Jersey","Saint Barthelemy","Saint Martin" 205 | ); 206 | } 207 | function geoip_load_shared_mem ($file) { 208 | 209 | $fp = fopen($file, "rb"); 210 | if (!$fp) { 211 | print "error opening $file: $php_errormsg\n"; 212 | exit; 213 | } 214 | $s_array = fstat($fp); 215 | $size = $s_array['size']; 216 | if ($shmid = @shmop_open (GEOIP_SHM_KEY, "w", 0, 0)) { 217 | shmop_delete ($shmid); 218 | shmop_close ($shmid); 219 | } 220 | $shmid = shmop_open (GEOIP_SHM_KEY, "c", 0644, $size); 221 | shmop_write ($shmid, fread($fp, $size), 0); 222 | shmop_close ($shmid); 223 | } 224 | 225 | function _setup_segments($gi){ 226 | $gi->databaseType = GEOIP_COUNTRY_EDITION; 227 | $gi->record_length = STANDARD_RECORD_LENGTH; 228 | if ($gi->flags & GEOIP_SHARED_MEMORY) { 229 | $offset = @shmop_size ($gi->shmid) - 3; 230 | for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { 231 | $delim = @shmop_read ($gi->shmid, $offset, 3); 232 | $offset += 3; 233 | if ($delim == (chr(255).chr(255).chr(255))) { 234 | $gi->databaseType = ord(@shmop_read ($gi->shmid, $offset, 1)); 235 | $offset++; 236 | 237 | if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ 238 | $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; 239 | } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ 240 | $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; 241 | } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0)|| 242 | ($gi->databaseType == GEOIP_CITY_EDITION_REV1) 243 | || ($gi->databaseType == GEOIP_ORG_EDITION) 244 | || ($gi->databaseType == GEOIP_ISP_EDITION) 245 | || ($gi->databaseType == GEOIP_ASNUM_EDITION)){ 246 | $gi->databaseSegments = 0; 247 | $buf = @shmop_read ($gi->shmid, $offset, SEGMENT_RECORD_LENGTH); 248 | for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ 249 | $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); 250 | } 251 | if (($gi->databaseType == GEOIP_ORG_EDITION)|| 252 | ($gi->databaseType == GEOIP_ISP_EDITION)) { 253 | $gi->record_length = ORG_RECORD_LENGTH; 254 | } 255 | } 256 | break; 257 | } else { 258 | $offset -= 4; 259 | } 260 | } 261 | if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| 262 | ($gi->databaseType == GEOIP_PROXY_EDITION)|| 263 | ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ 264 | $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; 265 | } 266 | } else { 267 | $filepos = ftell($gi->filehandle); 268 | fseek($gi->filehandle, -3, SEEK_END); 269 | for ($i = 0; $i < STRUCTURE_INFO_MAX_SIZE; $i++) { 270 | $delim = fread($gi->filehandle,3); 271 | if ($delim == (chr(255).chr(255).chr(255))){ 272 | $gi->databaseType = ord(fread($gi->filehandle,1)); 273 | if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ 274 | $gi->databaseSegments = GEOIP_STATE_BEGIN_REV0; 275 | } 276 | else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1){ 277 | $gi->databaseSegments = GEOIP_STATE_BEGIN_REV1; 278 | } else if (($gi->databaseType == GEOIP_CITY_EDITION_REV0) || 279 | ($gi->databaseType == GEOIP_CITY_EDITION_REV1) || 280 | ($gi->databaseType == GEOIP_ORG_EDITION) || 281 | ($gi->databaseType == GEOIP_ISP_EDITION) || 282 | ($gi->databaseType == GEOIP_ASNUM_EDITION)){ 283 | $gi->databaseSegments = 0; 284 | $buf = fread($gi->filehandle,SEGMENT_RECORD_LENGTH); 285 | for ($j = 0;$j < SEGMENT_RECORD_LENGTH;$j++){ 286 | $gi->databaseSegments += (ord($buf[$j]) << ($j * 8)); 287 | } 288 | if ($gi->databaseType == GEOIP_ORG_EDITION || 289 | $gi->databaseType == GEOIP_ISP_EDITION) { 290 | $gi->record_length = ORG_RECORD_LENGTH; 291 | } 292 | } 293 | break; 294 | } else { 295 | fseek($gi->filehandle, -4, SEEK_CUR); 296 | } 297 | } 298 | if (($gi->databaseType == GEOIP_COUNTRY_EDITION)|| 299 | ($gi->databaseType == GEOIP_PROXY_EDITION)|| 300 | ($gi->databaseType == GEOIP_NETSPEED_EDITION)){ 301 | $gi->databaseSegments = GEOIP_COUNTRY_BEGIN; 302 | } 303 | fseek($gi->filehandle,$filepos,SEEK_SET); 304 | } 305 | return $gi; 306 | } 307 | 308 | function geoip_open($filename, $flags) { 309 | $gi = new GeoIP; 310 | $gi->flags = $flags; 311 | if ($gi->flags & GEOIP_SHARED_MEMORY) { 312 | $gi->shmid = @shmop_open (GEOIP_SHM_KEY, "a", 0, 0); 313 | } else { 314 | $gi->filehandle = fopen($filename,"rb") or die( "Can not open $filename\n" ); 315 | if ($gi->flags & GEOIP_MEMORY_CACHE) { 316 | $s_array = fstat($gi->filehandle); 317 | $gi->memory_buffer = fread($gi->filehandle, $s_array['size']); 318 | } 319 | } 320 | 321 | $gi = _setup_segments($gi); 322 | return $gi; 323 | } 324 | 325 | function geoip_close($gi) { 326 | if ($gi->flags & GEOIP_SHARED_MEMORY) { 327 | return true; 328 | } 329 | 330 | return fclose($gi->filehandle); 331 | } 332 | 333 | function geoip_country_id_by_name($gi, $name) { 334 | $addr = gethostbyname($name); 335 | if (!$addr || $addr == $name) { 336 | return false; 337 | } 338 | return geoip_country_id_by_addr($gi, $addr); 339 | } 340 | 341 | function geoip_country_code_by_name($gi, $name) { 342 | $country_id = geoip_country_id_by_name($gi,$name); 343 | if ($country_id !== false) { 344 | return $gi->GEOIP_COUNTRY_CODES[$country_id]; 345 | } 346 | return false; 347 | } 348 | 349 | function geoip_country_name_by_name($gi, $name) { 350 | $country_id = geoip_country_id_by_name($gi,$name); 351 | if ($country_id !== false) { 352 | return $gi->GEOIP_COUNTRY_NAMES[$country_id]; 353 | } 354 | return false; 355 | } 356 | 357 | function geoip_country_id_by_addr($gi, $addr) { 358 | $ipnum = ip2long($addr); 359 | return _geoip_seek_country($gi, $ipnum) - GEOIP_COUNTRY_BEGIN; 360 | } 361 | 362 | function geoip_country_code_by_addr($gi, $addr) { 363 | if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { 364 | $record = geoip_record_by_addr($gi,$addr); 365 | if ( $record !== false ) { 366 | return $record->country_code; 367 | } 368 | } else { 369 | $country_id = geoip_country_id_by_addr($gi,$addr); 370 | if ($country_id !== false) { 371 | return $gi->GEOIP_COUNTRY_CODES[$country_id]; 372 | } 373 | } 374 | return false; 375 | } 376 | 377 | function geoip_country_name_by_addr($gi, $addr) { 378 | if ($gi->databaseType == GEOIP_CITY_EDITION_REV1) { 379 | $record = geoip_record_by_addr($gi,$addr); 380 | return $record->country_name; 381 | } else { 382 | $country_id = geoip_country_id_by_addr($gi,$addr); 383 | if ($country_id !== false) { 384 | return $gi->GEOIP_COUNTRY_NAMES[$country_id]; 385 | } 386 | } 387 | return false; 388 | } 389 | 390 | function _geoip_seek_country($gi, $ipnum) { 391 | $offset = 0; 392 | for ($depth = 31; $depth >= 0; --$depth) { 393 | if ($gi->flags & GEOIP_MEMORY_CACHE) { 394 | $buf = substr($gi->memory_buffer, 395 | 2 * $gi->record_length * $offset, 396 | 2 * $gi->record_length); 397 | } elseif ($gi->flags & GEOIP_SHARED_MEMORY) { 398 | $buf = @shmop_read ($gi->shmid, 399 | 2 * $gi->record_length * $offset, 400 | 2 * $gi->record_length ); 401 | } else { 402 | fseek($gi->filehandle, 2 * $gi->record_length * $offset, SEEK_SET) == 0 403 | or die("fseek failed"); 404 | $buf = fread($gi->filehandle, 2 * $gi->record_length); 405 | } 406 | $x = array(0,0); 407 | for ($i = 0; $i < 2; ++$i) { 408 | for ($j = 0; $j < $gi->record_length; ++$j) { 409 | $x[$i] += ord($buf[$gi->record_length * $i + $j]) << ($j * 8); 410 | } 411 | } 412 | if ($ipnum & (1 << $depth)) { 413 | if ($x[1] >= $gi->databaseSegments) { 414 | return $x[1]; 415 | } 416 | $offset = $x[1]; 417 | } else { 418 | if ($x[0] >= $gi->databaseSegments) { 419 | return $x[0]; 420 | } 421 | $offset = $x[0]; 422 | } 423 | } 424 | trigger_error("error traversing database - perhaps it is corrupt?", E_USER_ERROR); 425 | return false; 426 | } 427 | 428 | function _get_org($gi,$ipnum){ 429 | $seek_org = _geoip_seek_country($gi,$ipnum); 430 | if ($seek_org == $gi->databaseSegments) { 431 | return NULL; 432 | } 433 | $record_pointer = $seek_org + (2 * $gi->record_length - 1) * $gi->databaseSegments; 434 | if ($gi->flags & GEOIP_SHARED_MEMORY) { 435 | $org_buf = @shmop_read ($gi->shmid, $record_pointer, MAX_ORG_RECORD_LENGTH); 436 | } else { 437 | fseek($gi->filehandle, $record_pointer, SEEK_SET); 438 | $org_buf = fread($gi->filehandle,MAX_ORG_RECORD_LENGTH); 439 | } 440 | $org_buf = substr($org_buf, 0, strpos($org_buf, 0)); 441 | return $org_buf; 442 | } 443 | 444 | function geoip_org_by_addr ($gi,$addr) { 445 | if ($addr == NULL) { 446 | return 0; 447 | } 448 | $ipnum = ip2long($addr); 449 | return _get_org($gi, $ipnum); 450 | } 451 | 452 | function _get_region($gi,$ipnum){ 453 | if ($gi->databaseType == GEOIP_REGION_EDITION_REV0){ 454 | $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV0; 455 | if ($seek_region >= 1000){ 456 | $country_code = "US"; 457 | $region = chr(($seek_region - 1000)/26 + 65) . chr(($seek_region - 1000)%26 + 65); 458 | } else { 459 | $country_code = $gi->GEOIP_COUNTRY_CODES[$seek_region]; 460 | $region = ""; 461 | } 462 | return array ($country_code,$region); 463 | } else if ($gi->databaseType == GEOIP_REGION_EDITION_REV1) { 464 | $seek_region = _geoip_seek_country($gi,$ipnum) - GEOIP_STATE_BEGIN_REV1; 465 | //print $seek_region; 466 | if ($seek_region < US_OFFSET){ 467 | $country_code = ""; 468 | $region = ""; 469 | } else if ($seek_region < CANADA_OFFSET) { 470 | $country_code = "US"; 471 | $region = chr(($seek_region - US_OFFSET)/26 + 65) . chr(($seek_region - US_OFFSET)%26 + 65); 472 | } else if ($seek_region < WORLD_OFFSET) { 473 | $country_code = "CA"; 474 | $region = chr(($seek_region - CANADA_OFFSET)/26 + 65) . chr(($seek_region - CANADA_OFFSET)%26 + 65); 475 | } else { 476 | $country_code = $gi->GEOIP_COUNTRY_CODES[($seek_region - WORLD_OFFSET) / FIPS_RANGE]; 477 | $region = ""; 478 | } 479 | return array ($country_code,$region); 480 | } 481 | } 482 | 483 | function geoip_region_by_addr ($gi,$addr) { 484 | if ($addr == NULL) { 485 | return 0; 486 | } 487 | $ipnum = ip2long($addr); 488 | return _get_region($gi, $ipnum); 489 | } 490 | 491 | function getdnsattributes ($l,$ip){ 492 | $r = new Net_DNS_Resolver(); 493 | $r->nameservers = array("ws1.maxmind.com"); 494 | $p = $r->search($l."." . $ip .".s.maxmind.com","TXT","IN"); 495 | $str = is_object($p->answer[0])?$p->answer[0]->string():''; 496 | ereg("\"(.*)\"",$str,$regs); 497 | $str = $regs[1]; 498 | return $str; 499 | } 500 | 501 | ?> 502 | -------------------------------------------------------------------------------- /includes/config.php: -------------------------------------------------------------------------------- 1 | error = 'ERROR: Empty config file path'; 20 | return FALSE; 21 | } 22 | if(!file_exists($filepath)){ 23 | $this->error = 'ERROR: Config file not found: '.$filepath; 24 | return FALSE; 25 | } 26 | $this->config_file = $filepath; 27 | return $this->load(); 28 | } 29 | 30 | function load(){ 31 | $CONFIG = @parse_ini_file($this->config_file, TRUE); 32 | if(!$CONFIG){ 33 | $this->error = 'ERROR: Unable to open config file: '.$this->config_file; 34 | return FALSE; 35 | } 36 | $this->items = $CONFIG; 37 | return TRUE; 38 | } 39 | 40 | function error_msg(){ 41 | return $this->error; 42 | } 43 | } 44 | ?> -------------------------------------------------------------------------------- /process.php: -------------------------------------------------------------------------------- 1 | error_msg()); 14 | 15 | // Database connection 16 | $db_username = $CONFIG->items['Database']['Username']; 17 | $db_password = $CONFIG->items['Database']['Password']; 18 | $db_host = $CONFIG->items['Database']['Server']; 19 | $db_database = $CONFIG->items['Database']['Database']; 20 | 21 | $DB = new mysqli($db_host, $db_username, $db_password, $db_database); 22 | 23 | $handle = @fopen($CONFIG->items['Common']['NginxAccessLogLocation'], "r"); 24 | if ($handle) { 25 | while (($line = fgets($handle, 4096)) !== false) { 26 | 27 | $line_data = json_decode($line); 28 | if($line_data) 29 | { 30 | if($line_data->status == "200" && strpos($line_data->request, 'ET '. $CONFIG->items['Common']['NginxStreamFolder'])) 31 | { 32 | //Time 33 | $transfer_time = logdate_to_mysqldatetime($line_data->time_local); 34 | 35 | //Check if time is already recorded 36 | $query = 'SELECT time FROM `last_update`'; 37 | $result = $DB->query($query); 38 | if (!$result) { 39 | $message = 'Invalid query: ' . $DB->error . "\n"; 40 | $message .= 'Whole query: ' . $query; 41 | die($message); 42 | } else { 43 | $resultoutput = $result->fetch_assoc(); 44 | } 45 | $result->close(); 46 | 47 | if($resultoutput['time'] <= $transfer_time) 48 | { 49 | //IP-Address 50 | $ip_addr = $line_data->remote_addr; 51 | 52 | //User Agent 53 | $user_agent = $line_data->http_user_agent; 54 | 55 | //Connection ID 56 | $connection_id = $line_data->connection; 57 | 58 | //Checksum with connection 59 | $client_id_w_conn = md5($ip_addr.$connection_id.$user_agent); 60 | 61 | //Checksum with connection 62 | $client_id = md5($ip_addr.$user_agent); 63 | 64 | //Bytes Transfered 65 | $bytes_transfered = $line_data->bytes_sent; 66 | 67 | //StreamName 68 | $PathToStream = explode(' ', $line_data->request)[1]; 69 | $PathToStream = explode($CONFIG->items['Common']['NginxStreamFolder'], $PathToStream)[1]; 70 | if(!strpos($PathToStream, '.m3u8') && $PathToStream != '') 71 | { 72 | $stream_path = explode('/', $PathToStream)[0]; 73 | $stream_path = explode('_', $stream_path); 74 | 75 | $stream_name = $stream_path[0]; 76 | $stream_quality = $stream_path[1]; 77 | 78 | //TODO: Not implemented 79 | $location = ""; 80 | 81 | //Save Log to Database 82 | $DB->query('INSERT INTO `log` ' 83 | . '(`c-client-id`, `c-client-id-conn`, `c-ip`,`c-agent`' 84 | . ',`c-ip-country`, `streamname`, `streamquality`,' 85 | . '`connection-id`, `timestamp`, `bytes`) VALUES' 86 | . '("'.$client_id.'", "'.$client_id_w_conn.'", "'.$ip_addr.'",' 87 | . '"'.$user_agent.'", "'.$location.'",' 88 | . '"'.$stream_name.'", "'.$stream_quality.'",' 89 | . '"'.$connection_id.'",' 90 | . '"'.$transfer_time.'", "'.$bytes_transfered.'")'); 91 | 92 | $DB->query('UPDATE `last_update` SET time = "'.$transfer_time.'"'); 93 | } 94 | } 95 | } 96 | } 97 | } 98 | if (!feof($handle)) { 99 | echo "Fehler: unerwarteter fgets() Fehlschlag\n"; 100 | } 101 | fclose($handle); 102 | } 103 | 104 | //Evaluate Inputs 105 | //Check if time is already recorded 106 | $query = 'SELECT `id`, `c-client-id`, `c-ip`, `c-agent`, `c-ip-country`, `streamname`, `timestamp`, `bytes` FROM ' 107 | . '`log` WHERE evaluated = 0 ORDER BY timestamp ASC'; 108 | $result = $DB->query($query); 109 | if (!$result) { 110 | $message = 'Invalid query: ' . $DB->error . "\n"; 111 | $message .= 'Whole query: ' . $query; 112 | die($message); 113 | } else { 114 | while ($loginfo=$result->fetch_object()) 115 | { 116 | 117 | //Check if client-id is already recorded within last 2 minutes 118 | $query = 'SELECT COUNT(*) as cnt FROM `connections` ' 119 | . 'WHERE `c-client-id` = "'.$loginfo->{'c-client-id'}.'" AND ' 120 | . '`streamname` = "'.$loginfo->streamname.'" AND "' 121 | . $loginfo->timestamp.'" BETWEEN ' 122 | . '`timestamp-end` AND DATE_ADD(`timestamp-end`, INTERVAL 1 MINUTE)'; 123 | 124 | $result_connections = $DB->query($query); 125 | if (!$result_connections) { 126 | $message = 'Invalid query: ' . $DB->error . "\n"; 127 | $message .= 'Whole query: ' . $query; 128 | die($message); 129 | } else { 130 | $resultoutput = $result_connections->fetch_assoc(); 131 | } 132 | $result_connections->close(); 133 | if($resultoutput['cnt'] > 0) 134 | { 135 | $query = 'UPDATE `connections` SET ' 136 | . '`bytes` = `bytes` + '.$loginfo->bytes.', ' 137 | . '`timestamp-end` = "'.$loginfo->timestamp.'", ' 138 | . '`duration` = TIME_TO_SEC(TIMEDIFF("'.$loginfo->timestamp.'", `timestamp-start`)) ' 139 | . 'WHERE `c-client-id` ="'.$loginfo->{'c-client-id'}.'" AND ' 140 | . '`streamname` = "'.$loginfo->streamname.'" AND "' 141 | . $loginfo->timestamp.'" BETWEEN ' 142 | . '`timestamp-end` AND DATE_ADD(`timestamp-end`, INTERVAL 1 MINUTE)'; 143 | 144 | //Update 145 | $DB->query($query); 146 | 147 | } else { 148 | //Insert 149 | $DB->query('INSERT INTO `connections` ' 150 | . '(`c-client-id`, `c-ip`,`c-agent`' 151 | . ',`c-ip-country`, `streamname`, `timestamp-start`,' 152 | . '`timestamp-end`, `bytes`, `duration`) VALUES' 153 | . '("'.$loginfo->{'c-client-id'}.'", "'.$loginfo->{'c-ip'}.'", "'.$loginfo->{'c-agent'}.'",' 154 | . '"'.$loginfo->{'c-ip-country'}.'", "'.$loginfo->streamname.'", "'.$loginfo->timestamp.'",' 155 | . '"'.$loginfo->timestamp.'", "'.$loginfo->bytes.'", "0")'); 156 | } 157 | //Update log entry to evaluated 158 | $DB->query('UPDATE `log` SET evaluated = "1" WHERE id = '.$loginfo->id); 159 | } 160 | // Free result set 161 | $result->close(); 162 | } 163 | 164 | // Open log files 165 | /*if ($handle = opendir($CONFIG->items['Common']['LogDirectory'])) { 166 | while (false !== ($file = readdir($handle))) { 167 | if ($file != "." && $file != "..") { 168 | 169 | // Process a log file 170 | echo "File: $file\n"; 171 | echo $CONFIG->items['Common']['LogDirectory'] . $DIRSEP . $file; 172 | $fh = fopen($CONFIG->items['Common']['LogDirectory'] . $DIRSEP . $file, 'r'); 173 | $row = 1; 174 | while ($line = fgets($fh, 4096) !== FALSE) { 175 | 176 | echo $line; 177 | 178 | $whitespace_splits = explode(' ', $line); 179 | var_dump($whitespace_splits); 180 | $ip_addr = $whitespace_splits[0]; 181 | echo $ip_addr . "
"; 182 | 183 | // Count fields in a row 184 | $num = count($data); 185 | echo $num; 186 | if ($num > 1) { 187 | // Column names 188 | //echo "

$num fields in line $row:

\n"; 189 | if (substr($data[0], 0, 8) == '#Fields:') { 190 | // Row of Column names 191 | $ColumnNames = array(); 192 | for ($c = 0; $c < $num; $c++) { 193 | //echo $data[$c] . "
\n"; 194 | if ($c == 0) 195 | $data[$c] = substr($data[$c], 9); 196 | $ColumnNames[$data[$c]] = $c; 197 | } 198 | //print_r($ColumnNames); 199 | }else { 200 | // Log row 201 | //$column = $ColumnNames['x-file-name']; 202 | //echo "$file ($row,".$column."): ".$data[$column]."\n"; 203 | // Filters 204 | if (isset($CONFIG->items['Filter']['Virtualhost'])) 205 | if ($data[$ColumnNames['x-vhost']] != $CONFIG->items['Filter']['Virtualhost']) { 206 | //print "Virtualhost Filter does not match: ".$data[$ColumnNames['x-vhost']]."!=".$CONFIG->items['Filter']['Virtualhost']."\n"; 207 | continue; 208 | } else { 209 | //print "Virtualhost Filter does match: ".$data[$ColumnNames['x-vhost']]."==".$CONFIG->items['Filter']['Virtualhost']."\n"; 210 | } 211 | 212 | // Create log rows 213 | $column = $ColumnNames['c-client-id']; 214 | $d = $data[$column]; 215 | if ($d != '-') { 216 | $ClientArray[$d]['c-ip'] = $data[$ColumnNames['c-ip']]; 217 | if ($data[$ColumnNames['x-file-name']] != '-') 218 | $ClientArray[$d]['x-file-name'] = $data[$ColumnNames['x-file-name']]; 219 | if ($data[$ColumnNames['x-sname']] != '-') 220 | $ClientArray[$d]['x-sname'] = $data[$ColumnNames['x-sname']]; 221 | $ClientArray[$d]['log'][$data[$ColumnNames['x-event']]] = array( 222 | 'x-event' => $data[$ColumnNames['x-event']], 223 | 'x-category' => $data[$ColumnNames['x-category']], 224 | 'date' => $data[$ColumnNames['date']], 225 | 'time' => $data[$ColumnNames['time']], 226 | 'tz' => $data[$ColumnNames['tz']], 227 | 'timestamp' => strtotime($data[$ColumnNames['date']] . ' ' . $data[$ColumnNames['time']] . ' ' . $data[$ColumnNames['tz']]), 228 | 'x-duration' => $data[$ColumnNames['x-duration']], 229 | 'sc-bytes' => $data[$ColumnNames['sc-bytes']], 230 | 'sc-stream-bytes' => $data[$ColumnNames['sc-stream-bytes']], 231 | ); 232 | } 233 | } 234 | $row++; 235 | }else { 236 | // Comment or empty line 237 | } 238 | } 239 | fclose($fh); 240 | } 241 | } 242 | closedir($handle); 243 | } 244 | 245 | $query = "INSERT INTO fmslog () VALUES "; 246 | $query_values = ''; 247 | $LogArray = array(); 248 | foreach ($ClientArray as $ck => $cv) { 249 | $c_client_id = $ck; 250 | $c_ip = $cv['c-ip']; 251 | $c_ip_country = geoip_country_name_by_addr($gi, $cv['c-ip']); 252 | $x_file_name = isset($cv['x-file-name']) ? substr($cv['x-file-name'], 0, 60) : '-'; 253 | $x_sname = isset($cv['x-sname']) ? $cv['x-sname'] : '-'; 254 | $connect_timestamp = isset($cv['log']['connect']['timestamp']) ? $cv['log']['connect']['timestamp'] : 0; 255 | $disconnect_timestamp = isset($cv['log']['disconnect']['timestamp']) ? $cv['log']['disconnect']['timestamp'] : 0; 256 | $play_timestamp = isset($cv['log']['play']['timestamp']) ? $cv['log']['play']['timestamp'] : 0; 257 | $stop_timestamp = isset($cv['log']['stop']['timestamp']) ? $cv['log']['stop']['timestamp'] : 0; 258 | $pause_timestamp = isset($cv['log']['pause']['timestamp']) ? $cv['log']['pause']['timestamp'] : 0; 259 | $unpause_timestamp = isset($cv['log']['unpause']['timestamp']) ? $cv['log']['unpause']['timestamp'] : 0; 260 | $x_duration = isset($cv['log']['stop']['x-duration']) ? $cv['log']['stop']['x-duration'] : 0; 261 | $sc_bytes = (isset($cv['log']['disconnect']['sc-bytes']) AND isset($cv['log']['connect']['sc-bytes'])) ? $cv['log']['disconnect']['sc-bytes'] - $cv['log']['connect']['sc-bytes'] : 0; 262 | $sc_stream_bytes = (isset($cv['log']['play']['sc-stream-bytes']) AND isset($cv['log']['stop']['sc-stream-bytes'])) ? $cv['log']['stop']['sc-stream-bytes'] - $cv['log']['play']['sc-stream-bytes'] : 0; 263 | 264 | if ($j > 19) { 265 | $result = mysql_query($query . $query_values, $DB); 266 | if (!$result) { 267 | $message = 'Invalid query: ' . mysql_error() . "; "; 268 | $message .= 'Whole query: ' . $query; 269 | print "$message\n"; 270 | } 271 | $query_values = ''; 272 | $j = 0; 273 | } 274 | if ($query_values) 275 | $query_values .= ', '; 276 | $query_values .= "($c_client_id, '$c_ip', '$c_ip_country', '$x_file_name', '$x_sname', $connect_timestamp, $disconnect_timestamp, $play_timestamp, $stop_timestamp, $pause_timestamp, $unpause_timestamp, $x_duration, $sc_bytes, $sc_stream_bytes)"; 277 | $j++; 278 | 279 | $i++; 280 | } 281 | $result = mysql_query($query . $query_values, $DB); 282 | if (!$result) { 283 | $message = 'Invalid query: ' . mysql_error() . "; "; 284 | $message .= 'Whole query: ' . $query; 285 | print "$message\n"; 286 | }*/ 287 | 288 | $endtime = time(); 289 | $runtime_in_sec = $endtime - $starttime; 290 | 291 | echo "Running time: ".$runtime_in_sec."sec; "; 292 | 293 | function logdate_to_mysqldatetime($timestring) 294 | { 295 | $timestring = str_replace_first(':' , ' ', $timestring); 296 | $timestring = str_replace('/', '-', $timestring); 297 | 298 | // Instantiate a DateTime with microseconds. 299 | $d = new DateTime($timestring); 300 | 301 | // Output the date with microseconds. 302 | return $d->format('Y-m-d H:i:s'); // 2011-01-01 15:03:01 303 | } 304 | 305 | function str_replace_first($from, $to, $subject) 306 | { 307 | $from = '/'.preg_quote($from, '/').'/'; 308 | 309 | return preg_replace($from, $to, $subject, 1); 310 | } 311 | ?> -------------------------------------------------------------------------------- /webroot/OFC/open-flash-chart.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openHPI/nginx-hls-analyzer/3bdcba05b6a8fd25f386f77c4da2f74506164ccb/webroot/OFC/open-flash-chart.swf -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/JSON.php: -------------------------------------------------------------------------------- 1 | 51 | * @author Matt Knapp 52 | * @author Brett Stimmerman 53 | * @copyright 2005 Michal Migurski 54 | * @version CVS: $Id: JSON.php,v 1.31 2006/06/28 05:54:17 migurski Exp $ 55 | * @license http://www.opensource.org/licenses/bsd-license.php 56 | * @link http://pear.php.net/pepr/pepr-proposal-show.php?id=198 57 | */ 58 | 59 | /** 60 | * Marker constant for Services_JSON::decode(), used to flag stack state 61 | */ 62 | define('SERVICES_JSON_SLICE', 1); 63 | 64 | /** 65 | * Marker constant for Services_JSON::decode(), used to flag stack state 66 | */ 67 | define('SERVICES_JSON_IN_STR', 2); 68 | 69 | /** 70 | * Marker constant for Services_JSON::decode(), used to flag stack state 71 | */ 72 | define('SERVICES_JSON_IN_ARR', 3); 73 | 74 | /** 75 | * Marker constant for Services_JSON::decode(), used to flag stack state 76 | */ 77 | define('SERVICES_JSON_IN_OBJ', 4); 78 | 79 | /** 80 | * Marker constant for Services_JSON::decode(), used to flag stack state 81 | */ 82 | define('SERVICES_JSON_IN_CMT', 5); 83 | 84 | /** 85 | * Behavior switch for Services_JSON::decode() 86 | */ 87 | define('SERVICES_JSON_LOOSE_TYPE', 16); 88 | 89 | /** 90 | * Behavior switch for Services_JSON::decode() 91 | */ 92 | define('SERVICES_JSON_SUPPRESS_ERRORS', 32); 93 | 94 | /** 95 | * Converts to and from JSON format. 96 | * 97 | * Brief example of use: 98 | * 99 | * 100 | * // create a new instance of Services_JSON 101 | * $json = new Services_JSON(); 102 | * 103 | * // convert a complexe value to JSON notation, and send it to the browser 104 | * $value = array('foo', 'bar', array(1, 2, 'baz'), array(3, array(4))); 105 | * $output = $json->encode($value); 106 | * 107 | * print($output); 108 | * // prints: ["foo","bar",[1,2,"baz"],[3,[4]]] 109 | * 110 | * // accept incoming POST data, assumed to be in JSON notation 111 | * $input = file_get_contents('php://input', 1000000); 112 | * $value = $json->decode($input); 113 | * 114 | */ 115 | class Services_JSON 116 | { 117 | /** 118 | * constructs a new JSON instance 119 | * 120 | * @param int $use object behavior flags; combine with boolean-OR 121 | * 122 | * possible values: 123 | * - SERVICES_JSON_LOOSE_TYPE: loose typing. 124 | * "{...}" syntax creates associative arrays 125 | * instead of objects in decode(). 126 | * - SERVICES_JSON_SUPPRESS_ERRORS: error suppression. 127 | * Values which can't be encoded (e.g. resources) 128 | * appear as NULL instead of throwing errors. 129 | * By default, a deeply-nested resource will 130 | * bubble up with an error, so all return values 131 | * from encode() should be checked with isError() 132 | */ 133 | function Services_JSON($use = 0) 134 | { 135 | $this->use = $use; 136 | } 137 | 138 | /** 139 | * convert a string from one UTF-16 char to one UTF-8 char 140 | * 141 | * Normally should be handled by mb_convert_encoding, but 142 | * provides a slower PHP-only method for installations 143 | * that lack the multibye string extension. 144 | * 145 | * @param string $utf16 UTF-16 character 146 | * @return string UTF-8 character 147 | * @access private 148 | */ 149 | function utf162utf8($utf16) 150 | { 151 | // oh please oh please oh please oh please oh please 152 | if(function_exists('mb_convert_encoding')) { 153 | return mb_convert_encoding($utf16, 'UTF-8', 'UTF-16'); 154 | } 155 | 156 | $bytes = (ord($utf16{0}) << 8) | ord($utf16{1}); 157 | 158 | switch(true) { 159 | case ((0x7F & $bytes) == $bytes): 160 | // this case should never be reached, because we are in ASCII range 161 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 162 | return chr(0x7F & $bytes); 163 | 164 | case (0x07FF & $bytes) == $bytes: 165 | // return a 2-byte UTF-8 character 166 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 167 | return chr(0xC0 | (($bytes >> 6) & 0x1F)) 168 | . chr(0x80 | ($bytes & 0x3F)); 169 | 170 | case (0xFFFF & $bytes) == $bytes: 171 | // return a 3-byte UTF-8 character 172 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 173 | return chr(0xE0 | (($bytes >> 12) & 0x0F)) 174 | . chr(0x80 | (($bytes >> 6) & 0x3F)) 175 | . chr(0x80 | ($bytes & 0x3F)); 176 | } 177 | 178 | // ignoring UTF-32 for now, sorry 179 | return ''; 180 | } 181 | 182 | /** 183 | * convert a string from one UTF-8 char to one UTF-16 char 184 | * 185 | * Normally should be handled by mb_convert_encoding, but 186 | * provides a slower PHP-only method for installations 187 | * that lack the multibye string extension. 188 | * 189 | * @param string $utf8 UTF-8 character 190 | * @return string UTF-16 character 191 | * @access private 192 | */ 193 | function utf82utf16($utf8) 194 | { 195 | // oh please oh please oh please oh please oh please 196 | if(function_exists('mb_convert_encoding')) { 197 | return mb_convert_encoding($utf8, 'UTF-16', 'UTF-8'); 198 | } 199 | 200 | switch(strlen($utf8)) { 201 | case 1: 202 | // this case should never be reached, because we are in ASCII range 203 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 204 | return $utf8; 205 | 206 | case 2: 207 | // return a UTF-16 character from a 2-byte UTF-8 char 208 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 209 | return chr(0x07 & (ord($utf8{0}) >> 2)) 210 | . chr((0xC0 & (ord($utf8{0}) << 6)) 211 | | (0x3F & ord($utf8{1}))); 212 | 213 | case 3: 214 | // return a UTF-16 character from a 3-byte UTF-8 char 215 | // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 216 | return chr((0xF0 & (ord($utf8{0}) << 4)) 217 | | (0x0F & (ord($utf8{1}) >> 2))) 218 | . chr((0xC0 & (ord($utf8{1}) << 6)) 219 | | (0x7F & ord($utf8{2}))); 220 | } 221 | 222 | // ignoring UTF-32 for now, sorry 223 | return ''; 224 | } 225 | 226 | /** 227 | * encodes an arbitrary variable into JSON format 228 | * 229 | * @param mixed $var any number, boolean, string, array, or object to be encoded. 230 | * see argument 1 to Services_JSON() above for array-parsing behavior. 231 | * if var is a strng, note that encode() always expects it 232 | * to be in ASCII or UTF-8 format! 233 | * 234 | * @return mixed JSON string representation of input var or an error if a problem occurs 235 | * @access public 236 | */ 237 | function encode($var) 238 | { 239 | switch (gettype($var)) { 240 | case 'boolean': 241 | return $var ? 'true' : 'false'; 242 | 243 | case 'NULL': 244 | return 'null'; 245 | 246 | case 'integer': 247 | return (int) $var; 248 | 249 | case 'double': 250 | case 'float': 251 | return (float) $var; 252 | 253 | case 'string': 254 | // STRINGS ARE EXPECTED TO BE IN ASCII OR UTF-8 FORMAT 255 | $ascii = ''; 256 | $strlen_var = strlen($var); 257 | 258 | /* 259 | * Iterate over every character in the string, 260 | * escaping with a slash or encoding to UTF-8 where necessary 261 | */ 262 | for ($c = 0; $c < $strlen_var; ++$c) { 263 | 264 | $ord_var_c = ord($var{$c}); 265 | 266 | switch (true) { 267 | case $ord_var_c == 0x08: 268 | $ascii .= '\b'; 269 | break; 270 | case $ord_var_c == 0x09: 271 | $ascii .= '\t'; 272 | break; 273 | case $ord_var_c == 0x0A: 274 | $ascii .= '\n'; 275 | break; 276 | case $ord_var_c == 0x0C: 277 | $ascii .= '\f'; 278 | break; 279 | case $ord_var_c == 0x0D: 280 | $ascii .= '\r'; 281 | break; 282 | 283 | case $ord_var_c == 0x22: 284 | case $ord_var_c == 0x2F: 285 | case $ord_var_c == 0x5C: 286 | // double quote, slash, slosh 287 | $ascii .= '\\'.$var{$c}; 288 | break; 289 | 290 | case (($ord_var_c >= 0x20) && ($ord_var_c <= 0x7F)): 291 | // characters U-00000000 - U-0000007F (same as ASCII) 292 | $ascii .= $var{$c}; 293 | break; 294 | 295 | case (($ord_var_c & 0xE0) == 0xC0): 296 | // characters U-00000080 - U-000007FF, mask 110XXXXX 297 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 298 | $char = pack('C*', $ord_var_c, ord($var{$c + 1})); 299 | $c += 1; 300 | $utf16 = $this->utf82utf16($char); 301 | $ascii .= sprintf('\u%04s', bin2hex($utf16)); 302 | break; 303 | 304 | case (($ord_var_c & 0xF0) == 0xE0): 305 | // characters U-00000800 - U-0000FFFF, mask 1110XXXX 306 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 307 | $char = pack('C*', $ord_var_c, 308 | ord($var{$c + 1}), 309 | ord($var{$c + 2})); 310 | $c += 2; 311 | $utf16 = $this->utf82utf16($char); 312 | $ascii .= sprintf('\u%04s', bin2hex($utf16)); 313 | break; 314 | 315 | case (($ord_var_c & 0xF8) == 0xF0): 316 | // characters U-00010000 - U-001FFFFF, mask 11110XXX 317 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 318 | $char = pack('C*', $ord_var_c, 319 | ord($var{$c + 1}), 320 | ord($var{$c + 2}), 321 | ord($var{$c + 3})); 322 | $c += 3; 323 | $utf16 = $this->utf82utf16($char); 324 | $ascii .= sprintf('\u%04s', bin2hex($utf16)); 325 | break; 326 | 327 | case (($ord_var_c & 0xFC) == 0xF8): 328 | // characters U-00200000 - U-03FFFFFF, mask 111110XX 329 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 330 | $char = pack('C*', $ord_var_c, 331 | ord($var{$c + 1}), 332 | ord($var{$c + 2}), 333 | ord($var{$c + 3}), 334 | ord($var{$c + 4})); 335 | $c += 4; 336 | $utf16 = $this->utf82utf16($char); 337 | $ascii .= sprintf('\u%04s', bin2hex($utf16)); 338 | break; 339 | 340 | case (($ord_var_c & 0xFE) == 0xFC): 341 | // characters U-04000000 - U-7FFFFFFF, mask 1111110X 342 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 343 | $char = pack('C*', $ord_var_c, 344 | ord($var{$c + 1}), 345 | ord($var{$c + 2}), 346 | ord($var{$c + 3}), 347 | ord($var{$c + 4}), 348 | ord($var{$c + 5})); 349 | $c += 5; 350 | $utf16 = $this->utf82utf16($char); 351 | $ascii .= sprintf('\u%04s', bin2hex($utf16)); 352 | break; 353 | } 354 | } 355 | 356 | return '"'.$ascii.'"'; 357 | 358 | case 'array': 359 | /* 360 | * As per JSON spec if any array key is not an integer 361 | * we must treat the the whole array as an object. We 362 | * also try to catch a sparsely populated associative 363 | * array with numeric keys here because some JS engines 364 | * will create an array with empty indexes up to 365 | * max_index which can cause memory issues and because 366 | * the keys, which may be relevant, will be remapped 367 | * otherwise. 368 | * 369 | * As per the ECMA and JSON specification an object may 370 | * have any string as a property. Unfortunately due to 371 | * a hole in the ECMA specification if the key is a 372 | * ECMA reserved word or starts with a digit the 373 | * parameter is only accessible using ECMAScript's 374 | * bracket notation. 375 | */ 376 | 377 | // treat as a JSON object 378 | if (is_array($var) && count($var) && (array_keys($var) !== range(0, sizeof($var) - 1))) { 379 | $properties = array_map(array($this, 'name_value'), 380 | array_keys($var), 381 | array_values($var)); 382 | 383 | foreach($properties as $property) { 384 | if(Services_JSON::isError($property)) { 385 | return $property; 386 | } 387 | } 388 | 389 | return '{' . join(',', $properties) . '}'; 390 | } 391 | 392 | // treat it like a regular array 393 | $elements = array_map(array($this, 'encode'), $var); 394 | 395 | foreach($elements as $element) { 396 | if(Services_JSON::isError($element)) { 397 | return $element; 398 | } 399 | } 400 | 401 | return '[' . join(',', $elements) . ']'; 402 | 403 | case 'object': 404 | $vars = get_object_vars($var); 405 | 406 | $properties = array_map(array($this, 'name_value'), 407 | array_keys($vars), 408 | array_values($vars)); 409 | 410 | foreach($properties as $property) { 411 | if(Services_JSON::isError($property)) { 412 | return $property; 413 | } 414 | } 415 | 416 | return '{' . join(',', $properties) . '}'; 417 | 418 | default: 419 | return ($this->use & SERVICES_JSON_SUPPRESS_ERRORS) 420 | ? 'null' 421 | : new Services_JSON_Error(gettype($var)." can not be encoded as JSON string"); 422 | } 423 | } 424 | 425 | /** 426 | * array-walking function for use in generating JSON-formatted name-value pairs 427 | * 428 | * @param string $name name of key to use 429 | * @param mixed $value reference to an array element to be encoded 430 | * 431 | * @return string JSON-formatted name-value pair, like '"name":value' 432 | * @access private 433 | */ 434 | function name_value($name, $value) 435 | { 436 | $encoded_value = $this->encode($value); 437 | 438 | if(Services_JSON::isError($encoded_value)) { 439 | return $encoded_value; 440 | } 441 | 442 | return $this->encode(strval($name)) . ':' . $encoded_value; 443 | } 444 | 445 | /** 446 | * reduce a string by removing leading and trailing comments and whitespace 447 | * 448 | * @param $str string string value to strip of comments and whitespace 449 | * 450 | * @return string string value stripped of comments and whitespace 451 | * @access private 452 | */ 453 | function reduce_string($str) 454 | { 455 | $str = preg_replace(array( 456 | 457 | // eliminate single line comments in '// ...' form 458 | '#^\s*//(.+)$#m', 459 | 460 | // eliminate multi-line comments in '/* ... */' form, at start of string 461 | '#^\s*/\*(.+)\*/#Us', 462 | 463 | // eliminate multi-line comments in '/* ... */' form, at end of string 464 | '#/\*(.+)\*/\s*$#Us' 465 | 466 | ), '', $str); 467 | 468 | // eliminate extraneous space 469 | return trim($str); 470 | } 471 | 472 | /** 473 | * decodes a JSON string into appropriate variable 474 | * 475 | * @param string $str JSON-formatted string 476 | * 477 | * @return mixed number, boolean, string, array, or object 478 | * corresponding to given JSON input string. 479 | * See argument 1 to Services_JSON() above for object-output behavior. 480 | * Note that decode() always returns strings 481 | * in ASCII or UTF-8 format! 482 | * @access public 483 | */ 484 | function decode($str) 485 | { 486 | $str = $this->reduce_string($str); 487 | 488 | switch (strtolower($str)) { 489 | case 'true': 490 | return true; 491 | 492 | case 'false': 493 | return false; 494 | 495 | case 'null': 496 | return null; 497 | 498 | default: 499 | $m = array(); 500 | 501 | if (is_numeric($str)) { 502 | // Lookie-loo, it's a number 503 | 504 | // This would work on its own, but I'm trying to be 505 | // good about returning integers where appropriate: 506 | // return (float)$str; 507 | 508 | // Return float or int, as appropriate 509 | return ((float)$str == (integer)$str) 510 | ? (integer)$str 511 | : (float)$str; 512 | 513 | } elseif (preg_match('/^("|\').*(\1)$/s', $str, $m) && $m[1] == $m[2]) { 514 | // STRINGS RETURNED IN UTF-8 FORMAT 515 | $delim = substr($str, 0, 1); 516 | $chrs = substr($str, 1, -1); 517 | $utf8 = ''; 518 | $strlen_chrs = strlen($chrs); 519 | 520 | for ($c = 0; $c < $strlen_chrs; ++$c) { 521 | 522 | $substr_chrs_c_2 = substr($chrs, $c, 2); 523 | $ord_chrs_c = ord($chrs{$c}); 524 | 525 | switch (true) { 526 | case $substr_chrs_c_2 == '\b': 527 | $utf8 .= chr(0x08); 528 | ++$c; 529 | break; 530 | case $substr_chrs_c_2 == '\t': 531 | $utf8 .= chr(0x09); 532 | ++$c; 533 | break; 534 | case $substr_chrs_c_2 == '\n': 535 | $utf8 .= chr(0x0A); 536 | ++$c; 537 | break; 538 | case $substr_chrs_c_2 == '\f': 539 | $utf8 .= chr(0x0C); 540 | ++$c; 541 | break; 542 | case $substr_chrs_c_2 == '\r': 543 | $utf8 .= chr(0x0D); 544 | ++$c; 545 | break; 546 | 547 | case $substr_chrs_c_2 == '\\"': 548 | case $substr_chrs_c_2 == '\\\'': 549 | case $substr_chrs_c_2 == '\\\\': 550 | case $substr_chrs_c_2 == '\\/': 551 | if (($delim == '"' && $substr_chrs_c_2 != '\\\'') || 552 | ($delim == "'" && $substr_chrs_c_2 != '\\"')) { 553 | $utf8 .= $chrs{++$c}; 554 | } 555 | break; 556 | 557 | case preg_match('/\\\u[0-9A-F]{4}/i', substr($chrs, $c, 6)): 558 | // single, escaped unicode character 559 | $utf16 = chr(hexdec(substr($chrs, ($c + 2), 2))) 560 | . chr(hexdec(substr($chrs, ($c + 4), 2))); 561 | $utf8 .= $this->utf162utf8($utf16); 562 | $c += 5; 563 | break; 564 | 565 | case ($ord_chrs_c >= 0x20) && ($ord_chrs_c <= 0x7F): 566 | $utf8 .= $chrs{$c}; 567 | break; 568 | 569 | case ($ord_chrs_c & 0xE0) == 0xC0: 570 | // characters U-00000080 - U-000007FF, mask 110XXXXX 571 | //see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 572 | $utf8 .= substr($chrs, $c, 2); 573 | ++$c; 574 | break; 575 | 576 | case ($ord_chrs_c & 0xF0) == 0xE0: 577 | // characters U-00000800 - U-0000FFFF, mask 1110XXXX 578 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 579 | $utf8 .= substr($chrs, $c, 3); 580 | $c += 2; 581 | break; 582 | 583 | case ($ord_chrs_c & 0xF8) == 0xF0: 584 | // characters U-00010000 - U-001FFFFF, mask 11110XXX 585 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 586 | $utf8 .= substr($chrs, $c, 4); 587 | $c += 3; 588 | break; 589 | 590 | case ($ord_chrs_c & 0xFC) == 0xF8: 591 | // characters U-00200000 - U-03FFFFFF, mask 111110XX 592 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 593 | $utf8 .= substr($chrs, $c, 5); 594 | $c += 4; 595 | break; 596 | 597 | case ($ord_chrs_c & 0xFE) == 0xFC: 598 | // characters U-04000000 - U-7FFFFFFF, mask 1111110X 599 | // see http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 600 | $utf8 .= substr($chrs, $c, 6); 601 | $c += 5; 602 | break; 603 | 604 | } 605 | 606 | } 607 | 608 | return $utf8; 609 | 610 | } elseif (preg_match('/^\[.*\]$/s', $str) || preg_match('/^\{.*\}$/s', $str)) { 611 | // array, or object notation 612 | 613 | if ($str{0} == '[') { 614 | $stk = array(SERVICES_JSON_IN_ARR); 615 | $arr = array(); 616 | } else { 617 | if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 618 | $stk = array(SERVICES_JSON_IN_OBJ); 619 | $obj = array(); 620 | } else { 621 | $stk = array(SERVICES_JSON_IN_OBJ); 622 | $obj = new stdClass(); 623 | } 624 | } 625 | 626 | array_push($stk, array('what' => SERVICES_JSON_SLICE, 627 | 'where' => 0, 628 | 'delim' => false)); 629 | 630 | $chrs = substr($str, 1, -1); 631 | $chrs = $this->reduce_string($chrs); 632 | 633 | if ($chrs == '') { 634 | if (reset($stk) == SERVICES_JSON_IN_ARR) { 635 | return $arr; 636 | 637 | } else { 638 | return $obj; 639 | 640 | } 641 | } 642 | 643 | //print("\nparsing {$chrs}\n"); 644 | 645 | $strlen_chrs = strlen($chrs); 646 | 647 | for ($c = 0; $c <= $strlen_chrs; ++$c) { 648 | 649 | $top = end($stk); 650 | $substr_chrs_c_2 = substr($chrs, $c, 2); 651 | 652 | if (($c == $strlen_chrs) || (($chrs{$c} == ',') && ($top['what'] == SERVICES_JSON_SLICE))) { 653 | // found a comma that is not inside a string, array, etc., 654 | // OR we've reached the end of the character list 655 | $slice = substr($chrs, $top['where'], ($c - $top['where'])); 656 | array_push($stk, array('what' => SERVICES_JSON_SLICE, 'where' => ($c + 1), 'delim' => false)); 657 | //print("Found split at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 658 | 659 | if (reset($stk) == SERVICES_JSON_IN_ARR) { 660 | // we are in an array, so just push an element onto the stack 661 | array_push($arr, $this->decode($slice)); 662 | 663 | } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { 664 | // we are in an object, so figure 665 | // out the property name and set an 666 | // element in an associative array, 667 | // for now 668 | $parts = array(); 669 | 670 | if (preg_match('/^\s*(["\'].*[^\\\]["\'])\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 671 | // "name":value pair 672 | $key = $this->decode($parts[1]); 673 | $val = $this->decode($parts[2]); 674 | 675 | if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 676 | $obj[$key] = $val; 677 | } else { 678 | $obj->$key = $val; 679 | } 680 | } elseif (preg_match('/^\s*(\w+)\s*:\s*(\S.*),?$/Uis', $slice, $parts)) { 681 | // name:value pair, where name is unquoted 682 | $key = $parts[1]; 683 | $val = $this->decode($parts[2]); 684 | 685 | if ($this->use & SERVICES_JSON_LOOSE_TYPE) { 686 | $obj[$key] = $val; 687 | } else { 688 | $obj->$key = $val; 689 | } 690 | } 691 | 692 | } 693 | 694 | } elseif ((($chrs{$c} == '"') || ($chrs{$c} == "'")) && ($top['what'] != SERVICES_JSON_IN_STR)) { 695 | // found a quote, and we are not inside a string 696 | array_push($stk, array('what' => SERVICES_JSON_IN_STR, 'where' => $c, 'delim' => $chrs{$c})); 697 | //print("Found start of string at {$c}\n"); 698 | 699 | } elseif (($chrs{$c} == $top['delim']) && 700 | ($top['what'] == SERVICES_JSON_IN_STR) && 701 | ((strlen(substr($chrs, 0, $c)) - strlen(rtrim(substr($chrs, 0, $c), '\\'))) % 2 != 1)) { 702 | // found a quote, we're in a string, and it's not escaped 703 | // we know that it's not escaped becase there is _not_ an 704 | // odd number of backslashes at the end of the string so far 705 | array_pop($stk); 706 | //print("Found end of string at {$c}: ".substr($chrs, $top['where'], (1 + 1 + $c - $top['where']))."\n"); 707 | 708 | } elseif (($chrs{$c} == '[') && 709 | in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 710 | // found a left-bracket, and we are in an array, object, or slice 711 | array_push($stk, array('what' => SERVICES_JSON_IN_ARR, 'where' => $c, 'delim' => false)); 712 | //print("Found start of array at {$c}\n"); 713 | 714 | } elseif (($chrs{$c} == ']') && ($top['what'] == SERVICES_JSON_IN_ARR)) { 715 | // found a right-bracket, and we're in an array 716 | array_pop($stk); 717 | //print("Found end of array at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 718 | 719 | } elseif (($chrs{$c} == '{') && 720 | in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 721 | // found a left-brace, and we are in an array, object, or slice 722 | array_push($stk, array('what' => SERVICES_JSON_IN_OBJ, 'where' => $c, 'delim' => false)); 723 | //print("Found start of object at {$c}\n"); 724 | 725 | } elseif (($chrs{$c} == '}') && ($top['what'] == SERVICES_JSON_IN_OBJ)) { 726 | // found a right-brace, and we're in an object 727 | array_pop($stk); 728 | //print("Found end of object at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 729 | 730 | } elseif (($substr_chrs_c_2 == '/*') && 731 | in_array($top['what'], array(SERVICES_JSON_SLICE, SERVICES_JSON_IN_ARR, SERVICES_JSON_IN_OBJ))) { 732 | // found a comment start, and we are in an array, object, or slice 733 | array_push($stk, array('what' => SERVICES_JSON_IN_CMT, 'where' => $c, 'delim' => false)); 734 | $c++; 735 | //print("Found start of comment at {$c}\n"); 736 | 737 | } elseif (($substr_chrs_c_2 == '*/') && ($top['what'] == SERVICES_JSON_IN_CMT)) { 738 | // found a comment end, and we're in one now 739 | array_pop($stk); 740 | $c++; 741 | 742 | for ($i = $top['where']; $i <= $c; ++$i) 743 | $chrs = substr_replace($chrs, ' ', $i, 1); 744 | 745 | //print("Found end of comment at {$c}: ".substr($chrs, $top['where'], (1 + $c - $top['where']))."\n"); 746 | 747 | } 748 | 749 | } 750 | 751 | if (reset($stk) == SERVICES_JSON_IN_ARR) { 752 | return $arr; 753 | 754 | } elseif (reset($stk) == SERVICES_JSON_IN_OBJ) { 755 | return $obj; 756 | 757 | } 758 | 759 | } 760 | } 761 | } 762 | 763 | /** 764 | * @todo Ultimately, this should just call PEAR::isError() 765 | */ 766 | function isError($data, $code = null) 767 | { 768 | if (class_exists('pear')) { 769 | return PEAR::isError($data, $code); 770 | } elseif (is_object($data) && (get_class($data) == 'services_json_error' || 771 | is_subclass_of($data, 'services_json_error'))) { 772 | return true; 773 | } 774 | 775 | return false; 776 | } 777 | } 778 | 779 | if (class_exists('PEAR_Error')) { 780 | 781 | class Services_JSON_Error extends PEAR_Error 782 | { 783 | function Services_JSON_Error($message = 'unknown error', $code = null, 784 | $mode = null, $options = null, $userinfo = null) 785 | { 786 | parent::PEAR_Error($message, $code, $mode, $options, $userinfo); 787 | } 788 | } 789 | 790 | } else { 791 | 792 | /** 793 | * @todo Ultimately, this class shall be descended from PEAR_Error 794 | */ 795 | class Services_JSON_Error 796 | { 797 | function Services_JSON_Error($message = 'unknown error', $code = null, 798 | $mode = null, $options = null, $userinfo = null) 799 | { 800 | 801 | } 802 | } 803 | 804 | } 805 | 806 | ?> 807 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/README.txt: -------------------------------------------------------------------------------- 1 | Open Flash Chart - PHP libraries. These help create data files for Open Flash Chart. 2 | Copyright (C) 2007 3 | 4 | This library is free software; you can redistribute it and/or 5 | modify it under the terms of the GNU Lesser General Public 6 | License as published by the Free Software Foundation; either 7 | version 2.1 of the License, or (at your option) any later version. 8 | 9 | This library is distributed in the hope that it will be useful, 10 | but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 | Lesser General Public License for more details. 13 | 14 | You should have received a copy of the GNU Lesser General Public 15 | License along with this library; if not, write to the Free Software 16 | Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/dot_base.php: -------------------------------------------------------------------------------- 1 | type = $type; 16 | if( isset( $value ) ) 17 | $this->value( $value ); 18 | } 19 | 20 | /** 21 | * For line charts that only require a Y position 22 | * for each point. 23 | * @param $value as integer, the Y position 24 | */ 25 | function value( $value ) 26 | { 27 | $this->value = $value; 28 | } 29 | 30 | /** 31 | * For scatter charts that require an X and Y position for 32 | * each point. 33 | * 34 | * @param $x as integer 35 | * @param $y as integer 36 | */ 37 | function position( $x, $y ) 38 | { 39 | $this->x = $x; 40 | $this->y = $y; 41 | } 42 | 43 | /** 44 | * @param $colour is a string, HEX colour, e.g. '#FF0000' red 45 | */ 46 | function colour($colour) 47 | { 48 | $this->colour = $colour; 49 | return $this; 50 | } 51 | 52 | /** 53 | * The tooltip for this dot. 54 | */ 55 | function tooltip( $tip ) 56 | { 57 | $this->tip = $tip; 58 | return $this; 59 | } 60 | 61 | /** 62 | * @param $size is an integer. Size of the dot. 63 | */ 64 | function size($size) 65 | { 66 | $tmp = 'dot-size'; 67 | $this->$tmp = $size; 68 | return $this; 69 | } 70 | 71 | /** 72 | * a private method 73 | */ 74 | function type( $type ) 75 | { 76 | $this->type = $type; 77 | return $this; 78 | } 79 | 80 | /** 81 | * @param $size is an integer. The size of the hollow 'halo' around the dot that masks the line. 82 | */ 83 | function halo_size( $size ) 84 | { 85 | $tmp = 'halo-size'; 86 | $this->$tmp = $size; 87 | return $this; 88 | } 89 | 90 | /** 91 | * @param $do as string. One of three options (examples): 92 | * - "http://example.com" - browse to this URL 93 | * - "https://example.com" - browse to this URL 94 | * - "trace:message" - print this message in the FlashDevelop debug pane 95 | * - all other strings will be called as Javascript functions, so a string "hello_world" 96 | * will call the JS function "hello_world(index)". It passes in the index of the 97 | * point. 98 | */ 99 | function on_click( $do ) 100 | { 101 | $tmp = 'on-click'; 102 | $this->$tmp = $do; 103 | } 104 | } 105 | 106 | /** 107 | * Draw a hollow dot 108 | */ 109 | class hollow_dot extends dot_base 110 | { 111 | function hollow_dot($value=null) 112 | { 113 | parent::dot_base( 'hollow-dot', $value ); 114 | } 115 | } 116 | 117 | /** 118 | * Draw a star 119 | */ 120 | class star extends dot_base 121 | { 122 | /** 123 | * The constructor, takes an optional $value 124 | */ 125 | function star($value=null) 126 | { 127 | parent::dot_base( 'star', $value ); 128 | } 129 | 130 | /** 131 | * @param $angle is an integer. 132 | */ 133 | function rotation($angle) 134 | { 135 | $this->rotation = $angle; 136 | return $this; 137 | } 138 | 139 | /** 140 | * @param $is_hollow is a boolean. 141 | */ 142 | function hollow($is_hollow) 143 | { 144 | $this->hollow = $is_hollow; 145 | } 146 | } 147 | 148 | /** 149 | * Draw a 'bow tie' shape. 150 | */ 151 | class bow extends dot_base 152 | { 153 | /** 154 | * The constructor, takes an optional $value 155 | */ 156 | function bow($value=null) 157 | { 158 | parent::dot_base( 'bow', $value ); 159 | } 160 | 161 | /** 162 | * Rotate the anchor object. 163 | * @param $angle is an integer. 164 | */ 165 | function rotation($angle) 166 | { 167 | $this->rotation = $angle; 168 | return $this; 169 | } 170 | } 171 | 172 | /** 173 | * An n sided shape. 174 | */ 175 | class anchor extends dot_base 176 | { 177 | /** 178 | * The constructor, takes an optional $value 179 | */ 180 | function anchor($value=null) 181 | { 182 | parent::dot_base( 'anchor', $value ); 183 | } 184 | 185 | /** 186 | * Rotate the anchor object. 187 | * @param $angle is an integer. 188 | */ 189 | function rotation($angle) 190 | { 191 | $this->rotation = $angle; 192 | return $this; 193 | } 194 | 195 | /** 196 | * @param $sides is an integer. Number of sides this shape has. 197 | */ 198 | function sides($sides) 199 | { 200 | $this->sides = $sides; 201 | return $this; 202 | } 203 | } 204 | 205 | /** 206 | * A simple dot 207 | */ 208 | class dot extends dot_base 209 | { 210 | /** 211 | * The constructor, takes an optional $value 212 | */ 213 | function dot($value=null) 214 | { 215 | parent::dot_base( 'dot', $value ); 216 | } 217 | } 218 | 219 | /** 220 | * A simple dot 221 | */ 222 | class solid_dot extends dot_base 223 | { 224 | /** 225 | * The constructor, takes an optional $value 226 | */ 227 | function solid_dot($value=null) 228 | { 229 | parent::dot_base( 'solid-dot', $value ); 230 | } 231 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/json_format.php: -------------------------------------------------------------------------------- 1 | 0 && $json[$c-1] != '\\') 76 | { 77 | $in_string = !$in_string; 78 | } 79 | default: 80 | $new_json .= $char; 81 | break; 82 | } 83 | } 84 | 85 | return $new_json; 86 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_area_base.php: -------------------------------------------------------------------------------- 1 | type = "area"; 11 | } 12 | 13 | /** 14 | * the fill colour 15 | */ 16 | function set_fill_colour( $colour ) 17 | { 18 | $this->fill = $colour; 19 | } 20 | 21 | /** 22 | * sugar: see set_fill_colour 23 | */ 24 | function fill_colour( $colour ) 25 | { 26 | $this->set_fill_colour( $colour ); 27 | return $this; 28 | } 29 | 30 | function set_fill_alpha( $alpha ) 31 | { 32 | $tmp = "fill-alpha"; 33 | $this->$tmp = $alpha; 34 | } 35 | 36 | function set_loop() 37 | { 38 | $this->loop = true; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_area_hollow.php: -------------------------------------------------------------------------------- 1 | type = "area_hollow"; 8 | parent::area_base(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_area_line.php: -------------------------------------------------------------------------------- 1 | type = "area_line"; 8 | parent::area_base(); 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_arrow.php: -------------------------------------------------------------------------------- 1 | type = "arrow"; 16 | $this->start = array("x"=>$x, "y"=>$y); 17 | $this->end = array("x"=>$a, "y"=>$b); 18 | $this->colour($colour); 19 | $this->{"barb-length"} = $barb_length; 20 | } 21 | 22 | function colour( $colour ) 23 | { 24 | $this->colour = $colour; 25 | return $this; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar.php: -------------------------------------------------------------------------------- 1 | top = $top; 10 | 11 | if( isset( $bottom ) ) 12 | $this->bottom = $bottom; 13 | } 14 | 15 | function set_colour( $colour ) 16 | { 17 | $this->colour = $colour; 18 | } 19 | 20 | function set_tooltip( $tip ) 21 | { 22 | $this->tip = $tip; 23 | } 24 | } 25 | 26 | class bar extends bar_base 27 | { 28 | function bar() 29 | { 30 | $this->type = "bar"; 31 | parent::bar_base(); 32 | } 33 | } 34 | 35 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_3d.php: -------------------------------------------------------------------------------- 1 | top = $top; 10 | } 11 | 12 | function set_colour( $colour ) 13 | { 14 | $this->colour = $colour; 15 | } 16 | 17 | function set_tooltip( $tip ) 18 | { 19 | $this->tip = $tip; 20 | } 21 | } 22 | 23 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_base.php: -------------------------------------------------------------------------------- 1 | text = $text; 16 | $tmp = 'font-size'; 17 | $this->$tmp = $size; 18 | } 19 | 20 | /** 21 | * syntatical sugar. 22 | */ 23 | function key( $text, $size ) 24 | { 25 | $this->set_key( $text, $size ); 26 | } 27 | 28 | /** 29 | * @param $v as an array, a mix of: 30 | * - a bar_value class. You can use this to customise the paramters of each bar. 31 | * - integer. This is the Y position of the top of the bar. 32 | */ 33 | function set_values( $v ) 34 | { 35 | $this->values = $v; 36 | } 37 | 38 | /** 39 | * see set_values 40 | */ 41 | function append_value( $v ) 42 | { 43 | $this->values[] = $v; 44 | } 45 | 46 | /** 47 | * @param $colour as string, a HEX colour, e.g. '#ff0000' red 48 | */ 49 | function set_colour( $colour ) 50 | { 51 | $this->colour = $colour; 52 | } 53 | 54 | /** 55 | *syntatical sugar 56 | */ 57 | function colour( $colour ) 58 | { 59 | $this->set_colour( $colour ); 60 | } 61 | 62 | /** 63 | * @param $alpha as real number (range 0 to 1), e.g. 0.5 is half transparent 64 | */ 65 | function set_alpha( $alpha ) 66 | { 67 | $this->alpha = $alpha; 68 | } 69 | 70 | /** 71 | * @param $tip as string, the tip to show. May contain various magic variables. 72 | */ 73 | function set_tooltip( $tip ) 74 | { 75 | $this->tip = $tip; 76 | } 77 | 78 | /** 79 | *@param $on_show as line_on_show object 80 | */ 81 | function set_on_show($on_show) 82 | { 83 | $this->{'on-show'} = $on_show; 84 | } 85 | 86 | function set_on_click( $text ) 87 | { 88 | $tmp = 'on-click'; 89 | $this->$tmp = $text; 90 | } 91 | 92 | function attach_to_right_y_axis() 93 | { 94 | $this->axis = 'right'; 95 | } 96 | } 97 | 98 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_filled.php: -------------------------------------------------------------------------------- 1 | $tmp = $outline_colour; 16 | } 17 | } 18 | 19 | class bar_filled extends bar_base 20 | { 21 | function bar_filled( $colour=null, $outline_colour=null ) 22 | { 23 | $this->type = "bar_filled"; 24 | parent::bar_base(); 25 | 26 | if( isset( $colour ) ) 27 | $this->set_colour( $colour ); 28 | 29 | if( isset( $outline_colour ) ) 30 | $this->set_outline_colour( $outline_colour ); 31 | } 32 | 33 | function set_outline_colour( $outline_colour ) 34 | { 35 | $tmp = 'outline-colour'; 36 | $this->$tmp = $outline_colour; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_glass.php: -------------------------------------------------------------------------------- 1 | type = $type; 22 | $this->cascade = (float)$cascade; 23 | $this->delay = (float)$delay; 24 | } 25 | } 26 | 27 | class bar_value 28 | { 29 | /** 30 | * @param $top as integer. The Y value of the top of the bar 31 | * @param OPTIONAL $bottom as integer. The Y value of the bottom of the bar, defaults to Y min. 32 | */ 33 | function bar_value( $top, $bottom=null ) 34 | { 35 | $this->top = $top; 36 | 37 | if( isset( $bottom ) ) 38 | $this->bottom = $bottom; 39 | } 40 | 41 | function set_colour( $colour ) 42 | { 43 | $this->colour = $colour; 44 | } 45 | 46 | function set_tooltip( $tip ) 47 | { 48 | $this->tip = $tip; 49 | } 50 | } 51 | 52 | class bar extends bar_base 53 | { 54 | function bar() 55 | { 56 | $this->type = "bar"; 57 | parent::bar_base(); 58 | } 59 | } 60 | 61 | class bar_glass extends bar_base 62 | { 63 | function bar_glass() 64 | { 65 | $this->type = "bar_glass"; 66 | parent::bar_base(); 67 | } 68 | } 69 | 70 | class bar_cylinder extends bar_base 71 | { 72 | function bar_cylinder() 73 | { 74 | $this->type = "bar_cylinder"; 75 | parent::bar_base(); 76 | } 77 | } 78 | 79 | class bar_cylinder_outline extends bar_base 80 | { 81 | function bar_cylinder_outline() 82 | { 83 | $this->type = "bar_cylinder_outline"; 84 | parent::bar_base(); 85 | } 86 | } 87 | 88 | class bar_rounded_glass extends bar_base 89 | { 90 | function bar_rounded_glass() 91 | { 92 | $this->type = "bar_round_glass"; 93 | parent::bar_base(); 94 | } 95 | } 96 | 97 | class bar_round extends bar_base 98 | { 99 | function bar_round() 100 | { 101 | $this->type = "bar_round"; 102 | parent::bar_base(); 103 | } 104 | } 105 | 106 | class bar_dome extends bar_base 107 | { 108 | function bar_dome() 109 | { 110 | $this->type = "bar_dome"; 111 | parent::bar_base(); 112 | } 113 | } 114 | 115 | class bar_round3d extends bar_base 116 | { 117 | function bar_round3d() 118 | { 119 | $this->type = "bar_round3d"; 120 | parent::bar_base(); 121 | } 122 | } 123 | 124 | class bar_3d extends bar_base 125 | { 126 | function bar_3d() 127 | { 128 | $this->type = "bar_3d"; 129 | parent::bar_base(); 130 | } 131 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_sketch.php: -------------------------------------------------------------------------------- 1 | type = "bar_sketch"; 16 | parent::bar_base(); 17 | 18 | $this->set_colour( $colour ); 19 | $this->set_outline_colour( $outline_colour ); 20 | $this->offset = $fun_factor; 21 | } 22 | 23 | function set_outline_colour( $outline_colour ) 24 | { 25 | $tmp = 'outline-colour'; 26 | $this->$tmp = $outline_colour; 27 | } 28 | } 29 | 30 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_bar_stack.php: -------------------------------------------------------------------------------- 1 | type = "bar_stack"; 10 | parent::bar_base(); 11 | } 12 | 13 | function append_stack( $v ) 14 | { 15 | $this->append_value( $v ); 16 | } 17 | 18 | // an array of HEX colours strings 19 | // e.g. array( '#ff0000', '#00ff00' ); 20 | function set_colours( $colours ) 21 | { 22 | $this->colours = $colours; 23 | } 24 | 25 | // an array of bar_stack_value 26 | function set_keys( $keys ) 27 | { 28 | $this->keys = $keys; 29 | } 30 | } 31 | 32 | class bar_stack_value 33 | { 34 | function bar_stack_value( $val, $colour ) 35 | { 36 | $this->val = $val; 37 | $this->colour = $colour; 38 | } 39 | 40 | function set_tooltip( $tip ) 41 | { 42 | $this->tip = $tip; 43 | } 44 | } 45 | 46 | class bar_stack_key 47 | { 48 | function bar_stack_key( $colour, $text, $font_size ) 49 | { 50 | $this->colour = $colour; 51 | $this->text = $text; 52 | $tmp = 'font-size'; 53 | $this->$tmp = $font_size; 54 | } 55 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_candle.php: -------------------------------------------------------------------------------- 1 | high = $high; 13 | $this->top = $open; 14 | $this->bottom = $close; 15 | $this->low = $low; 16 | } 17 | 18 | function set_colour( $colour ) 19 | { 20 | $this->colour = $colour; 21 | } 22 | 23 | function set_tooltip( $tip ) 24 | { 25 | $this->tip = $tip; 26 | } 27 | } 28 | 29 | class candle extends bar_base 30 | { 31 | function candle($colour, $negative_colour=null) 32 | { 33 | $this->type = "candle"; 34 | parent::bar_base(); 35 | 36 | $this->set_colour( $colour ); 37 | if(!is_null($negative_colour)) 38 | $this->{'negative-colour'} = $negative_colour; 39 | } 40 | } 41 | 42 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_hbar.php: -------------------------------------------------------------------------------- 1 | left = $left; 10 | $this->right = $right; 11 | } 12 | else 13 | $this->right = $left; 14 | } 15 | 16 | function set_colour( $colour ) 17 | { 18 | $this->colour = $colour; 19 | } 20 | 21 | function set_tooltip( $tip ) 22 | { 23 | $this->tip = $tip; 24 | } 25 | } 26 | 27 | class hbar 28 | { 29 | function hbar( $colour ) 30 | { 31 | $this->type = "hbar"; 32 | $this->values = array(); 33 | $this->set_colour( $colour ); 34 | } 35 | 36 | function append_value( $v ) 37 | { 38 | $this->values[] = $v; 39 | } 40 | 41 | function set_values( $v ) 42 | { 43 | foreach( $v as $val ) 44 | $this->append_value( new hbar_value( $val ) ); 45 | } 46 | 47 | function set_colour( $colour ) 48 | { 49 | $this->colour = $colour; 50 | } 51 | 52 | function set_key( $text, $size ) 53 | { 54 | $this->text = $text; 55 | $tmp = 'font-size'; 56 | $this->$tmp = $size; 57 | } 58 | 59 | function set_tooltip( $tip ) 60 | { 61 | $this->tip = $tip; 62 | } 63 | } 64 | 65 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_line.php: -------------------------------------------------------------------------------- 1 | type = $type; 20 | $this->cascade = (float)$cascade; 21 | $this->delay = (float)$delay; 22 | } 23 | } 24 | 25 | class line 26 | { 27 | function line() 28 | { 29 | $this->type = "line"; 30 | $this->values = array(); 31 | } 32 | 33 | /** 34 | * Set the default dot that all the real 35 | * dots inherit their properties from. If you set the 36 | * default dot to be red, all values in your chart that 37 | * do not specify a colour will be red. Same for all the 38 | * other attributes such as tooltip, on-click, size etc... 39 | * 40 | * @param $style as any class that inherits base_dot 41 | */ 42 | function set_default_dot_style( $style ) 43 | { 44 | $tmp = 'dot-style'; 45 | $this->$tmp = $style; 46 | } 47 | 48 | /** 49 | * @param $v as array, can contain any combination of: 50 | * - integer, Y position of the point 51 | * - any class that inherits from dot_base 52 | * - null 53 | */ 54 | function set_values( $v ) 55 | { 56 | $this->values = $v; 57 | } 58 | 59 | /** 60 | * Append a value to the line. 61 | * 62 | * @param mixed $v 63 | */ 64 | function append_value($v) 65 | { 66 | $this->values[] = $v; 67 | } 68 | 69 | function set_width( $width ) 70 | { 71 | $this->width = $width; 72 | } 73 | 74 | function set_colour( $colour ) 75 | { 76 | $this->colour = $colour; 77 | } 78 | 79 | /** 80 | * sytnatical sugar for set_colour 81 | */ 82 | function colour( $colour ) 83 | { 84 | $this->set_colour( $colour ); 85 | return $this; 86 | } 87 | 88 | function set_halo_size( $size ) 89 | { 90 | $tmp = 'halo-size'; 91 | $this->$tmp = $size; 92 | } 93 | 94 | function set_key( $text, $font_size ) 95 | { 96 | $this->text = $text; 97 | $tmp = 'font-size'; 98 | $this->$tmp = $font_size; 99 | } 100 | 101 | function set_tooltip( $tip ) 102 | { 103 | $this->tip = $tip; 104 | } 105 | 106 | /** 107 | * @param $text as string. A javascript function name as a string. The chart will 108 | * try to call this function, it will pass the chart id as the only parameter into 109 | * this function. E.g: 110 | * 111 | */ 112 | function set_on_click( $text ) 113 | { 114 | $tmp = 'on-click'; 115 | $this->$tmp = $text; 116 | } 117 | 118 | function loop() 119 | { 120 | $this->loop = true; 121 | } 122 | 123 | function line_style( $s ) 124 | { 125 | $tmp = "line-style"; 126 | $this->$tmp = $s; 127 | } 128 | 129 | /** 130 | * Sets the text for the line. 131 | * 132 | * @param string $text 133 | */ 134 | function set_text($text) 135 | { 136 | $this->text = $text; 137 | } 138 | 139 | function attach_to_right_y_axis() 140 | { 141 | $this->axis = 'right'; 142 | } 143 | 144 | /** 145 | *@param $on_show as line_on_show object 146 | */ 147 | function set_on_show($on_show) 148 | { 149 | $this->{'on-show'} = $on_show; 150 | } 151 | 152 | function on_show($on_show) 153 | { 154 | $this->set_on_show($on_show); 155 | return $this; 156 | } 157 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_line_base.php: -------------------------------------------------------------------------------- 1 | type = "line"; 8 | $this->text = "Page views"; 9 | $tmp = 'font-size'; 10 | $this->$tmp = 10; 11 | 12 | $this->values = array(); 13 | } 14 | 15 | function set_values( $v ) 16 | { 17 | $this->values = $v; 18 | } 19 | 20 | /** 21 | * Append a value to the line. 22 | * 23 | * @param mixed $v 24 | */ 25 | function append_value($v) 26 | { 27 | $this->values[] = $v; 28 | } 29 | 30 | function set_width( $width ) 31 | { 32 | $this->width = $width; 33 | } 34 | 35 | function set_colour( $colour ) 36 | { 37 | $this->colour = $colour; 38 | } 39 | 40 | function set_dot_size( $size ) 41 | { 42 | $tmp = 'dot-size'; 43 | $this->$tmp = $size; 44 | } 45 | 46 | function set_halo_size( $size ) 47 | { 48 | $tmp = 'halo-size'; 49 | $this->$tmp = $size; 50 | } 51 | 52 | function set_key( $text, $font_size ) 53 | { 54 | $this->text = $text; 55 | $tmp = 'font-size'; 56 | $this->$tmp = $font_size; 57 | } 58 | 59 | function set_tooltip( $tip ) 60 | { 61 | $this->tip = $tip; 62 | } 63 | 64 | function set_on_click( $text ) 65 | { 66 | $tmp = 'on-click'; 67 | $this->$tmp = $text; 68 | } 69 | 70 | function loop() 71 | { 72 | $this->loop = true; 73 | } 74 | 75 | function line_style( $s ) 76 | { 77 | $tmp = "line-style"; 78 | $this->$tmp = $s; 79 | } 80 | 81 | /** 82 | * Sets the text for the line. 83 | * 84 | * @param string $text 85 | */ 86 | function set_text($text) 87 | { 88 | $this->text = $text; 89 | } 90 | 91 | 92 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_line_dot.php: -------------------------------------------------------------------------------- 1 | value = $value; 8 | $this->colour = $colour; 9 | } 10 | 11 | function set_colour( $colour ) 12 | { 13 | $this->colour = $colour; 14 | } 15 | 16 | function set_size( $size ) 17 | { 18 | $this->size = $size; 19 | } 20 | 21 | function set_tooltip( $tip ) 22 | { 23 | $this->tip = $tip; 24 | } 25 | } 26 | 27 | class line_dot extends line_base 28 | { 29 | function line_dot() 30 | { 31 | $this->type = "line_dot"; 32 | } 33 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_line_hollow.php: -------------------------------------------------------------------------------- 1 | type = "line_hollow"; 8 | } 9 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_line_style.php: -------------------------------------------------------------------------------- 1 | style = "dash"; 8 | $this->on = $on; 9 | $this->off = $off; 10 | } 11 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_menu.php: -------------------------------------------------------------------------------- 1 | type = "text"; 14 | $this->text = $text; 15 | $tmp = 'javascript-function'; 16 | $this->$tmp = $javascript_function_name; 17 | } 18 | } 19 | 20 | class ofc_menu_item_camera 21 | { 22 | /** 23 | * @param $text as string. The menu item text. 24 | * @param $javascript_function_name as string. The javascript function name, the 25 | * js function takes one parameter, the chart ID. So for example, our js function 26 | * could look like this: 27 | * 28 | * function save_image( chart_id ) 29 | * { 30 | * alert( chart_id ); 31 | * } 32 | * 33 | * to make a menu item call this: ofc_menu_item_camera('Save chart', 'save_image'); 34 | */ 35 | function ofc_menu_item_camera($text, $javascript_function_name) 36 | { 37 | $this->type = "camera-icon"; 38 | $this->text = $text; 39 | $tmp = 'javascript-function'; 40 | $this->$tmp = $javascript_function_name; 41 | } 42 | } 43 | 44 | class ofc_menu 45 | { 46 | function ofc_menu($colour, $outline_colour) 47 | { 48 | $this->colour = $colour; 49 | $this->outline_colour = $outline_colour; 50 | } 51 | 52 | function values($values) 53 | { 54 | $this->values = $values; 55 | } 56 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_pie.php: -------------------------------------------------------------------------------- 1 | value = $value; 8 | $this->label = $label; 9 | } 10 | 11 | function set_colour( $colour ) 12 | { 13 | $this->colour = $colour; 14 | } 15 | 16 | function set_label( $label, $label_colour, $font_size ) 17 | { 18 | $this->label = $label; 19 | 20 | $tmp = 'label-colour'; 21 | $this->$tmp = $label_colour; 22 | 23 | $tmp = 'font-size'; 24 | $this->$tmp = $font_size; 25 | 26 | } 27 | 28 | function set_tooltip( $tip ) 29 | { 30 | $this->tip = $tip; 31 | } 32 | 33 | function on_click( $event ) 34 | { 35 | $tmp = 'on-click'; 36 | $this->$tmp = $event; 37 | } 38 | 39 | 40 | /** 41 | * An object that inherits from base_pie_animation 42 | */ 43 | function add_animation( $animation ) 44 | { 45 | if( !isset( $this->animate ) ) 46 | $this->animate = array(); 47 | 48 | $this->animate[] = $animation; 49 | 50 | return $this; 51 | } 52 | } 53 | 54 | class base_pie_animation{} 55 | 56 | /** 57 | * fade the pie slice from $alpha (pie set_alpha) to 100% opaque. 58 | */ 59 | class pie_fade extends base_pie_animation 60 | { 61 | function pie_fade() 62 | { 63 | $this->type="fade"; 64 | } 65 | } 66 | 67 | /** 68 | * Bounce the pie slice out a little 69 | */ 70 | class pie_bounce extends base_pie_animation 71 | { 72 | /** 73 | * @param $distance as integer, distance to bounce in pixels 74 | */ 75 | function pie_bounce( $distance ) 76 | { 77 | $this->type="bounce"; 78 | $this->distance = $distance; 79 | } 80 | } 81 | 82 | /** 83 | * Make a pie chart and fill it with pie slices 84 | */ 85 | class pie 86 | { 87 | function pie() 88 | { 89 | $this->type = 'pie'; 90 | } 91 | 92 | function set_colours( $colours ) 93 | { 94 | $this->colours = $colours; 95 | } 96 | 97 | /** 98 | * Sugar wrapped around set_colours 99 | */ 100 | function colours( $colours ) 101 | { 102 | $this->set_colours( $colours ); 103 | return $this; 104 | } 105 | 106 | /** 107 | * @param $alpha as float (0-1) 0.75 = 3/4 visible 108 | */ 109 | function set_alpha( $alpha ) 110 | { 111 | $this->alpha = $alpha; 112 | } 113 | 114 | /** 115 | *sugar wrapped set_alpha 116 | **/ 117 | function alpha( $alpha ) 118 | { 119 | $this->set_alpha( $alpha ); 120 | return $this; 121 | } 122 | 123 | /** 124 | * @param $v as array containing one of 125 | * - null 126 | * - real or integer number 127 | * - a pie_value object 128 | */ 129 | function set_values( $v ) 130 | { 131 | $this->values = $v; 132 | } 133 | 134 | /** 135 | * sugar for set_values 136 | */ 137 | function values( $v ) 138 | { 139 | $this->set_values( $v ); 140 | return $this; 141 | } 142 | 143 | /** 144 | * HACK to keep old code working. 145 | */ 146 | function set_animate( $bool ) 147 | { 148 | if( $bool ) 149 | $this->add_animation( new pie_fade() ); 150 | 151 | } 152 | 153 | /** 154 | * An object that inherits from base_pie_animation 155 | */ 156 | function add_animation( $animation ) 157 | { 158 | if( !isset( $this->animate ) ) 159 | $this->animate = array(); 160 | 161 | $this->animate[] = $animation; 162 | 163 | return $this; 164 | } 165 | 166 | /** 167 | * @param $angle as real number 168 | */ 169 | function set_start_angle( $angle ) 170 | { 171 | $tmp = 'start-angle'; 172 | $this->$tmp = $angle; 173 | } 174 | 175 | /** 176 | * sugar for set_start_angle 177 | */ 178 | function start_angle($angle) 179 | { 180 | $this->set_start_angle( $angle ); 181 | return $this; 182 | } 183 | 184 | /** 185 | * @param $tip as string. The tooltip text. May contain magic varibles 186 | */ 187 | function set_tooltip( $tip ) 188 | { 189 | $this->tip = $tip; 190 | } 191 | 192 | /** 193 | * sugar for set_tooltip 194 | */ 195 | function tooltip( $tip ) 196 | { 197 | $this->set_tooltip( $tip ); 198 | return $this; 199 | } 200 | 201 | function set_gradient_fill() 202 | { 203 | $tmp = 'gradient-fill'; 204 | $this->$tmp = true; 205 | } 206 | 207 | function gradient_fill() 208 | { 209 | $this->set_gradient_fill(); 210 | return $this; 211 | } 212 | 213 | /** 214 | * By default each label is the same colour as the slice, 215 | * but you can ovveride that behaviour using this method. 216 | * 217 | * @param $label_colour as string HEX colour; 218 | */ 219 | function set_label_colour( $label_colour ) 220 | { 221 | $tmp = 'label-colour'; 222 | $this->$tmp = $label_colour; 223 | } 224 | 225 | function label_colour( $label_colour ) 226 | { 227 | $this->set_label_colour( $label_colour ); 228 | return $this; 229 | } 230 | 231 | /** 232 | * Turn off the labels 233 | */ 234 | function set_no_labels() 235 | { 236 | $tmp = 'no-labels'; 237 | $this->$tmp = true; 238 | } 239 | 240 | function on_click( $event ) 241 | { 242 | $tmp = 'on-click'; 243 | $this->$tmp = $event; 244 | } 245 | 246 | /** 247 | * Fix the radius of the pie chart. Take a look at the magic variable #radius# 248 | * for helping figure out what radius to set it to. 249 | * 250 | * @param $radius as number 251 | */ 252 | function radius( $radius ) 253 | { 254 | $this->radius = $radius; 255 | return $this; 256 | } 257 | } 258 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_radar_axis.php: -------------------------------------------------------------------------------- 1 | set_max( $max ); 8 | } 9 | 10 | function set_max( $max ) 11 | { 12 | $this->max = $max; 13 | } 14 | 15 | function set_steps( $steps ) 16 | { 17 | $this->steps = $steps; 18 | } 19 | 20 | function set_stroke( $s ) 21 | { 22 | $this->stroke = $s; 23 | } 24 | 25 | function set_colour( $colour ) 26 | { 27 | $this->colour = $colour; 28 | } 29 | 30 | function set_grid_colour( $colour ) 31 | { 32 | $tmp = 'grid-colour'; 33 | $this->$tmp = $colour; 34 | } 35 | 36 | function set_labels( $labels ) 37 | { 38 | $this->labels = $labels; 39 | } 40 | 41 | function set_spoke_labels( $labels ) 42 | { 43 | $tmp = 'spoke-labels'; 44 | $this->$tmp = $labels; 45 | } 46 | } 47 | 48 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_radar_axis_labels.php: -------------------------------------------------------------------------------- 1 | labels = $labels; 9 | } 10 | 11 | function set_colour( $colour ) 12 | { 13 | $this->colour = $colour; 14 | } 15 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_radar_spoke_labels.php: -------------------------------------------------------------------------------- 1 | labels = $labels; 9 | } 10 | 11 | function set_colour( $colour ) 12 | { 13 | $this->colour = $colour; 14 | } 15 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_scatter.php: -------------------------------------------------------------------------------- 1 | x = $x; 8 | $this->y = $y; 9 | 10 | if( $dot_size > 0 ) 11 | { 12 | $tmp = 'dot-size'; 13 | $this->$tmp = $dot_size; 14 | } 15 | } 16 | } 17 | 18 | class scatter 19 | { 20 | function scatter( $colour ) 21 | { 22 | $this->type = "scatter"; 23 | $this->set_colour( $colour ); 24 | } 25 | 26 | function set_colour( $colour ) 27 | { 28 | $this->colour = $colour; 29 | } 30 | 31 | function set_default_dot_style( $style ) 32 | { 33 | $tmp = 'dot-style'; 34 | $this->$tmp = $style; 35 | } 36 | 37 | /** 38 | * @param $v as array, can contain any combination of: 39 | * - integer, Y position of the point 40 | * - any class that inherits from scatter_value 41 | * - null 42 | */ 43 | function set_values( $values ) 44 | { 45 | $this->values = $values; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_scatter_line.php: -------------------------------------------------------------------------------- 1 | type = "scatter_line"; 8 | $this->set_colour( $colour ); 9 | $this->set_width( $width ); 10 | } 11 | 12 | function set_default_dot_style( $style ) 13 | { 14 | $tmp = 'dot-style'; 15 | $this->$tmp = $style; 16 | } 17 | 18 | function set_colour( $colour ) 19 | { 20 | $this->colour = $colour; 21 | } 22 | 23 | function set_width( $width ) 24 | { 25 | $this->width = $width; 26 | } 27 | 28 | function set_values( $values ) 29 | { 30 | $this->values = $values; 31 | } 32 | 33 | function set_step_horizontal() 34 | { 35 | $this->stepgraph = 'horizontal'; 36 | } 37 | 38 | function set_step_vertical() 39 | { 40 | $this->stepgraph = 'vertical'; 41 | } 42 | 43 | function set_key( $text, $font_size ) 44 | { 45 | $this->text = $text; 46 | $tmp = 'font-size'; 47 | $this->$tmp = $font_size; 48 | } 49 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_shape.php: -------------------------------------------------------------------------------- 1 | x = $x; 8 | $this->y = $y; 9 | } 10 | } 11 | 12 | class shape 13 | { 14 | function shape( $colour ) 15 | { 16 | $this->type = "shape"; 17 | $this->colour = $colour; 18 | $this->values = array(); 19 | } 20 | 21 | function append_value( $p ) 22 | { 23 | $this->values[] = $p; 24 | } 25 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_sugar.php: -------------------------------------------------------------------------------- 1 | colour($colour)->size($size); 16 | } 17 | } 18 | 19 | class s_box extends anchor 20 | { 21 | /** 22 | * I use this wrapper for default dot types, 23 | * it just makes the code easier to read. 24 | */ 25 | function s_box($colour, $size) 26 | { 27 | parent::anchor(); 28 | $this->colour($colour)->size($size)->rotation(45)->sides(4); 29 | } 30 | } 31 | 32 | class s_hollow_dot extends hollow_dot 33 | { 34 | /** 35 | * I use this wrapper for default dot types, 36 | * it just makes the code easier to read. 37 | */ 38 | function s_hollow_dot($colour, $size) 39 | { 40 | parent::hollow_dot(); 41 | $this->colour($colour)->size($size); 42 | } 43 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_tags.php: -------------------------------------------------------------------------------- 1 | type = "tags"; 8 | $this->values = array(); 9 | } 10 | 11 | function colour( $colour ) 12 | { 13 | $this->colour = $colour; 14 | return $this; 15 | } 16 | 17 | /** 18 | *@param $font as string. e.g. "Verdana" 19 | *@param $size as integer. Size in px 20 | */ 21 | function font($font, $size) 22 | { 23 | $this->font = $font; 24 | $this->{'font-size'} = $size; 25 | return $this; 26 | } 27 | 28 | /** 29 | *@param $x as integer. Size of x padding in px 30 | *@param $y as integer. Size of y padding in px 31 | */ 32 | function padding($x, $y) 33 | { 34 | $this->{"pad-x"} = $x; 35 | $this->{"pad-y"} = $y; 36 | return $this; 37 | } 38 | 39 | function rotate($angle) 40 | { 41 | $this->rotate($angle); 42 | return $this; 43 | } 44 | 45 | function align_x_center() 46 | { 47 | $this->{"align-x"} = "center"; 48 | return $this; 49 | } 50 | 51 | function align_x_left() 52 | { 53 | $this->{"align-x"} = "left"; 54 | return $this; 55 | } 56 | 57 | function align_x_right() 58 | { 59 | $this->{"align-x"} = "right"; 60 | return $this; 61 | } 62 | 63 | function align_y_above() 64 | { 65 | $this->{"align-y"} = "above"; 66 | return $this; 67 | } 68 | 69 | function align_y_below() 70 | { 71 | $this->{"align-y"} = "below"; 72 | return $this; 73 | } 74 | 75 | function align_y_center() 76 | { 77 | $this->{"align-y"} = "center"; 78 | return $this; 79 | } 80 | 81 | /** 82 | * This can contain some HTML, e.g: 83 | * - "More info" 84 | * - "ofc" 85 | */ 86 | function text($text) 87 | { 88 | $this->text = $text; 89 | return $this; 90 | } 91 | 92 | /** 93 | * This works, but to get the mouse pointer to change 94 | * to a little hand you need to use "stuff"-- see text() 95 | */ 96 | function on_click($on_click) 97 | { 98 | $this->{'on-click'} = $on_click; 99 | return $this; 100 | } 101 | 102 | /** 103 | *@param $bold boolean. 104 | *@param $underline boolean. 105 | *@param $border boolean. 106 | *@prarm $alpha real (0 to 1.0) 107 | */ 108 | function style($bold, $underline, $border, $alpha ) 109 | { 110 | $this->bold = $bold; 111 | $this->border = $underline; 112 | $this->underline = $border; 113 | $this->alpha = $alpha; 114 | return $this; 115 | } 116 | 117 | /** 118 | *@param $tag as ofc_tag 119 | */ 120 | function append_tag($tag) 121 | { 122 | $this->values[] = $tag; 123 | } 124 | } 125 | 126 | class ofc_tag extends ofc_tags 127 | { 128 | function ofc_tag($x, $y) 129 | { 130 | $this->x = $x; 131 | $this->y = $y; 132 | } 133 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_title.php: -------------------------------------------------------------------------------- 1 | text = $text; 12 | } 13 | 14 | /** 15 | * A css string. Can optionally contain: 16 | * - font-size 17 | * - font-family 18 | * - font-weight 19 | * - color 20 | * - background-color 21 | * - text-align 22 | * - margin 23 | * - margin-left 24 | * - margin-right 25 | * - margin-top 26 | * - margin-bottom 27 | * - padding 28 | * - padding-left 29 | * - padding-right 30 | * - padding-top 31 | * - padding-bottom 32 | * just like the css we use all the time :-) 33 | */ 34 | function set_style( $css ) 35 | { 36 | $this->style = $css; 37 | //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"; 38 | } 39 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_tooltip.php: -------------------------------------------------------------------------------- 1 | shadow = $shadow; 15 | } 16 | 17 | /** 18 | * @param $stroke as integer, border width in pixels (e.g. 5 ) 19 | */ 20 | function set_stroke( $stroke ) 21 | { 22 | $this->stroke = $stroke; 23 | } 24 | 25 | /** 26 | * @param $colour as string, HEX colour e.g. '#0000ff' 27 | */ 28 | function set_colour( $colour ) 29 | { 30 | $this->colour = $colour; 31 | } 32 | 33 | /** 34 | * @param $bg as string, HEX colour e.g. '#0000ff' 35 | */ 36 | function set_background_colour( $bg ) 37 | { 38 | $this->background = $bg; 39 | } 40 | 41 | /** 42 | * @param $style as string. A css style. 43 | */ 44 | function set_title_style( $style ) 45 | { 46 | $this->title = $style; 47 | } 48 | 49 | /** 50 | * @param $style as string. A css style. 51 | */ 52 | function set_body_style( $style ) 53 | { 54 | $this->body = $style; 55 | } 56 | 57 | function set_proximity() 58 | { 59 | $this->mouse = 1; 60 | } 61 | 62 | function set_hover() 63 | { 64 | $this->mouse = 2; 65 | } 66 | } 67 | 68 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_upload_image.php: -------------------------------------------------------------------------------- 1 | save_image debug mode, you 5 | // will see the 'echo' text in a new window. 6 | // 7 | 8 | /* 9 | 10 | print_r( $_GET ); 11 | print_r( $_POST ); 12 | print_r( $_FILES ); 13 | 14 | print_r( $GLOBALS ); 15 | print_r( $GLOBALS["HTTP_RAW_POST_DATA"] ); 16 | 17 | */ 18 | 19 | 20 | // default path for the image to be stored // 21 | $default_path = '../tmp-upload-images/'; 22 | 23 | if (!file_exists($default_path)) mkdir($default_path, 0777, true); 24 | 25 | // full path to the saved image including filename // 26 | $destination = $default_path . basename( $_GET[ 'name' ] ); 27 | 28 | echo 'Saving your image to: '. $destination; 29 | // print_r( $_POST ); 30 | // print_r( $_SERVER ); 31 | // echo $HTTP_RAW_POST_DATA; 32 | 33 | // 34 | // POST data is usually string data, but we are passing a RAW .png 35 | // so PHP is a bit confused and $_POST is empty. But it has saved 36 | // the raw bits into $HTTP_RAW_POST_DATA 37 | // 38 | 39 | $jfh = fopen($destination, 'w') or die("can't open file"); 40 | fwrite($jfh, $HTTP_RAW_POST_DATA); 41 | fclose($jfh); 42 | 43 | // 44 | // LOOK: 45 | // 46 | exit(); 47 | 48 | 49 | // 50 | // PHP5: 51 | // 52 | 53 | 54 | // default path for the image to be stored // 55 | $default_path = 'tmp-upload-images/'; 56 | 57 | if (!file_exists($default_path)) mkdir($default_path, 0777, true); 58 | 59 | // full path to the saved image including filename // 60 | $destination = $default_path . basename( $_FILES[ 'Filedata' ][ 'name' ] ); 61 | 62 | // move the image into the specified directory // 63 | if (move_uploaded_file($_FILES[ 'Filedata' ][ 'tmp_name' ], $destination)) { 64 | echo "The file " . basename( $_FILES[ 'Filedata' ][ 'name' ] ) . " has been uploaded;"; 65 | } else { 66 | echo "FILE UPLOAD FAILED"; 67 | } 68 | 69 | 70 | ?> 71 | -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_x_axis.php: -------------------------------------------------------------------------------- 1 | stroke = $stroke; 13 | } 14 | 15 | function stroke( $stroke ) 16 | { 17 | $this->set_stroke( $stroke ); 18 | return $this; 19 | } 20 | 21 | /** 22 | *@param $colour as string HEX colour 23 | *@param $grid_colour as string HEX colour 24 | */ 25 | function set_colours( $colour, $grid_colour ) 26 | { 27 | $this->set_colour( $colour ); 28 | $this->set_grid_colour( $grid_colour ); 29 | } 30 | 31 | /** 32 | *@param $colour as string HEX colour 33 | */ 34 | function set_colour( $colour ) 35 | { 36 | $this->colour = $colour; 37 | } 38 | 39 | function colour( $colour ) 40 | { 41 | $this->set_colour($colour); 42 | return $this; 43 | } 44 | 45 | function set_tick_height( $height ) 46 | { 47 | $tmp = 'tick-height'; 48 | $this->$tmp = $height; 49 | } 50 | 51 | function tick_height( $height ) 52 | { 53 | $this->set_tick_height($height); 54 | return $this; 55 | } 56 | 57 | function set_grid_colour( $colour ) 58 | { 59 | $tmp = 'grid-colour'; 60 | $this->$tmp = $colour; 61 | } 62 | 63 | function grid_colour( $colour ) 64 | { 65 | $this->set_grid_colour($colour); 66 | return $this; 67 | } 68 | 69 | /** 70 | * @param $o is a boolean. If true, the X axis start half a step in 71 | * This defaults to True 72 | */ 73 | function set_offset( $o ) 74 | { 75 | $this->offset = $o?true:false; 76 | } 77 | 78 | function offset( $o ) 79 | { 80 | $this->set_offset($o); 81 | return $this; 82 | } 83 | 84 | /** 85 | * @param $steps as integer. Which grid lines and ticks are visible. 86 | */ 87 | function set_steps( $steps ) 88 | { 89 | $this->steps = $steps; 90 | } 91 | 92 | function steps( $steps ) 93 | { 94 | $this->set_steps($steps); 95 | return $this; 96 | } 97 | 98 | /** 99 | * @param $val as an integer, the height in pixels of the 3D bar. Mostly 100 | * used for the 3D bar chart. 101 | */ 102 | function set_3d( $val ) 103 | { 104 | $tmp = '3d'; 105 | $this->$tmp = $val; 106 | } 107 | 108 | /** 109 | * @param $x_axis_labels as an x_axis_labels object 110 | * Use this to customize the labels (colour, font, etc...) 111 | */ 112 | function set_labels( $x_axis_labels ) 113 | { 114 | //$this->labels = $v; 115 | $this->labels = $x_axis_labels; 116 | } 117 | 118 | /** 119 | * Sugar syntax: helper function to make the examples simpler. 120 | * @param $a is an array of labels 121 | */ 122 | function set_labels_from_array( $a ) 123 | { 124 | $x_axis_labels = new x_axis_labels(); 125 | $x_axis_labels->set_labels( $a ); 126 | $this->labels = $x_axis_labels; 127 | 128 | if( isset( $this->steps ) ) 129 | $x_axis_labels->set_steps( $this->steps ); 130 | } 131 | 132 | /** 133 | * min and max. 134 | */ 135 | function set_range( $min, $max ) 136 | { 137 | $this->min = $min; 138 | $this->max = $max; 139 | } 140 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_x_axis_label.php: -------------------------------------------------------------------------------- 1 | set_text( $text ); 11 | $this->set_colour( $colour ); 12 | $this->set_size( $size ); 13 | $this->set_rotate( $rotate ); 14 | } 15 | 16 | function set_text( $text ) 17 | { 18 | $this->text = $text; 19 | } 20 | 21 | function set_colour( $colour ) 22 | { 23 | $this->colour = $colour; 24 | } 25 | 26 | function set_size( $size ) 27 | { 28 | $this->size = $size; 29 | } 30 | 31 | function set_rotate( $rotate ) 32 | { 33 | $this->rotate = $rotate; 34 | } 35 | 36 | function set_vertical() 37 | { 38 | $this->rotate = "vertical"; 39 | } 40 | 41 | function set_visible() 42 | { 43 | $this->visible = true; 44 | } 45 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_x_axis_labels.php: -------------------------------------------------------------------------------- 1 | steps = $steps; 13 | } 14 | 15 | /** 16 | * @param $steps as integer which labels are visible 17 | */ 18 | function visible_steps( $steps ) 19 | { 20 | $this->{"visible-steps"} = $steps; 21 | return $this; 22 | } 23 | 24 | /** 25 | * 26 | * @param $labels as an array of [x_axis_label or string] 27 | */ 28 | function set_labels( $labels ) 29 | { 30 | $this->labels = $labels; 31 | } 32 | 33 | function set_colour( $colour ) 34 | { 35 | $this->colour = $colour; 36 | } 37 | 38 | /** 39 | * font size in pixels 40 | */ 41 | function set_size( $size ) 42 | { 43 | $this->size = $size; 44 | } 45 | 46 | /** 47 | * rotate labels 48 | */ 49 | function set_vertical() 50 | { 51 | $this->rotate = 270; 52 | } 53 | 54 | /** 55 | * @param @angle as real. The angle of the text. 56 | */ 57 | function rotate( $angle ) 58 | { 59 | $this->rotate = $angle; 60 | } 61 | 62 | /** 63 | * @param $text as string. Replace and magic variables with actual x axis position. 64 | */ 65 | function text( $text ) 66 | { 67 | $this->text = $text; 68 | } 69 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_x_legend.php: -------------------------------------------------------------------------------- 1 | text = $text; 8 | } 9 | 10 | function set_style( $css ) 11 | { 12 | $this->style = $css; 13 | //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"; 14 | } 15 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_y_axis.php: -------------------------------------------------------------------------------- 1 | $tmp = $colour; 15 | } 16 | 17 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_y_axis_base.php: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openHPI/nginx-hls-analyzer/3bdcba05b6a8fd25f386f77c4da2f74506164ccb/webroot/OFC/php-ofc-library/ofc_y_axis_base.php -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_y_axis_label.php: -------------------------------------------------------------------------------- 1 | y = $y; 11 | $this->set_text( $text ); 12 | } 13 | 14 | function set_text( $text ) 15 | { 16 | $this->text = $text; 17 | } 18 | 19 | function set_colour( $colour ) 20 | { 21 | $this->colour = $colour; 22 | } 23 | 24 | function set_size( $size ) 25 | { 26 | $this->size = $size; 27 | } 28 | 29 | function set_rotate( $rotate ) 30 | { 31 | $this->rotate = $rotate; 32 | } 33 | 34 | function set_vertical() 35 | { 36 | $this->rotate = "vertical"; 37 | } 38 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_y_axis_labels.php: -------------------------------------------------------------------------------- 1 | steps = $steps; 13 | } 14 | 15 | /** 16 | * 17 | * @param $labels as an array of [y_axis_label or string] 18 | */ 19 | function set_labels( $labels ) 20 | { 21 | $this->labels = $labels; 22 | } 23 | 24 | function set_colour( $colour ) 25 | { 26 | $this->colour = $colour; 27 | } 28 | 29 | /** 30 | * font size in pixels 31 | */ 32 | function set_size( $size ) 33 | { 34 | $this->size = $size; 35 | } 36 | 37 | /** 38 | * rotate labels 39 | */ 40 | function set_vertical() 41 | { 42 | $this->rotate = 270; 43 | } 44 | 45 | function rotate( $angle ) 46 | { 47 | $this->rotate = $angle; 48 | } 49 | 50 | /** 51 | * @param $text default text that all labels inherit 52 | */ 53 | function set_text( $text ) 54 | { 55 | $this->text = $text; 56 | } 57 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/ofc_y_axis_right.php: -------------------------------------------------------------------------------- 1 | text = $text; 8 | } 9 | 10 | function set_style( $css ) 11 | { 12 | $this->style = $css; 13 | //"{font-size: 20px; color:#0000ff; font-family: Verdana; text-align: center;}"; 14 | } 15 | } -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/open-flash-chart-object.php: -------------------------------------------------------------------------------- 1 | '; 65 | 66 | if( !isset( $open_flash_chart_seqno ) ) 67 | { 68 | $open_flash_chart_seqno = 1; 69 | $out[] = ''; 70 | } 71 | else 72 | { 73 | $open_flash_chart_seqno++; 74 | $obj_id .= '_'. $open_flash_chart_seqno; 75 | $div_name .= '_'. $open_flash_chart_seqno; 76 | } 77 | 78 | if( $use_swfobject ) 79 | { 80 | // Using library for auto-enabling Flash object on IE, disabled-Javascript proof 81 | $out[] = '
'; 82 | $out[] = ''; 90 | $out[] = ''; 105 | } 106 | 107 | return implode("\n",$out); 108 | } 109 | ?> -------------------------------------------------------------------------------- /webroot/OFC/php-ofc-library/open-flash-chart.php: -------------------------------------------------------------------------------- 1 | title = new title( "Many data lines" ); 68 | $this->elements = array(); 69 | } 70 | 71 | function set_title( $t ) 72 | { 73 | $this->title = $t; 74 | } 75 | 76 | function set_x_axis( $x ) 77 | { 78 | $this->x_axis = $x; 79 | } 80 | 81 | function set_y_axis( $y ) 82 | { 83 | $this->y_axis = $y; 84 | } 85 | 86 | function add_y_axis( $y ) 87 | { 88 | $this->y_axis = $y; 89 | } 90 | 91 | function set_y_axis_right( $y ) 92 | { 93 | $this->y_axis_right = $y; 94 | } 95 | 96 | function add_element( $e ) 97 | { 98 | $this->elements[] = $e; 99 | } 100 | 101 | function set_x_legend( $x ) 102 | { 103 | $this->x_legend = $x; 104 | } 105 | 106 | function set_y_legend( $y ) 107 | { 108 | $this->y_legend = $y; 109 | } 110 | 111 | function set_bg_colour( $colour ) 112 | { 113 | $this->bg_colour = $colour; 114 | } 115 | 116 | function set_radar_axis( $radar ) 117 | { 118 | $this->radar_axis = $radar; 119 | } 120 | 121 | function set_tooltip( $tooltip ) 122 | { 123 | $this->tooltip = $tooltip; 124 | } 125 | 126 | /** 127 | * This is a bit funky :( 128 | * 129 | * @param $num_decimals as integer. Truncate the decimals to $num_decimals, e.g. set it 130 | * to 5 and 3.333333333 will display as 3.33333. 2.0 will display as 2 (or 2.00000 - see below) 131 | * @param $is_fixed_num_decimals_forced as boolean. If true it will pad the decimals. 132 | * @param $is_decimal_separator_comma as boolean 133 | * @param $is_thousand_separator_disabled as boolean 134 | * 135 | * This needs a bit of love and attention 136 | */ 137 | function set_number_format($num_decimals, $is_fixed_num_decimals_forced, $is_decimal_separator_comma, $is_thousand_separator_disabled ) 138 | { 139 | $this->num_decimals = $num_decimals; 140 | $this->is_fixed_num_decimals_forced = $is_fixed_num_decimals_forced; 141 | $this->is_decimal_separator_comma = $is_decimal_separator_comma; 142 | $this->is_thousand_separator_disabled = $is_thousand_separator_disabled; 143 | } 144 | 145 | /** 146 | * This is experimental and will change as we make it work 147 | * 148 | * @param $m as ofc_menu 149 | */ 150 | function set_menu($m) 151 | { 152 | $this->menu = $m; 153 | } 154 | 155 | function toString() 156 | { 157 | if (function_exists('json_encode')) 158 | { 159 | return json_encode($this); 160 | } 161 | else 162 | { 163 | $json = new Services_JSON(); 164 | return $json->encode( $this ); 165 | } 166 | } 167 | 168 | function toPrettyString() 169 | { 170 | return json_format( $this->toString() ); 171 | } 172 | } 173 | 174 | 175 | 176 | // 177 | // there is no PHP end tag so we don't mess the headers up! 178 | // -------------------------------------------------------------------------------- /webroot/concurrent.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 8 | 9 | // Database connection 10 | $db_username = $CONFIG->items['Database']['Username']; 11 | $db_password = $CONFIG->items['Database']['Password']; 12 | $db_host = $CONFIG->items['Database']['Server']; 13 | $db_database = $CONFIG->items['Database']['Database']; 14 | 15 | $DB = mysql_connect($db_host, $db_username, $db_password); 16 | if(!$DB) die(mysql_error()); 17 | $result = mysql_select_db($db_database, $DB); 18 | if(!$result) die(mysql_error()); 19 | 20 | $xtime = 0; 21 | 22 | if (isset ($_REQUEST["xtime"])) 23 | { 24 | $xtime = $_REQUEST["xtime"] + 0; 25 | } 26 | 27 | $liveonly = isset ($_REQUEST["live"]); 28 | $teletestonly = isset ($_REQUEST["teletest"]); 29 | 30 | ?> 31 | 33 | 34 | 35 | 36 | FMS Access Log Statistics 37 | 38 | 39 | 40 | 41 |

FMS Access Log Statistics - items['Common']['Sitename']; ?>

42 |

Time period: last 80 days 43 | | Page generated:

44 | 45 | 46 | 47 | 48 | 52 | 53 |

last 80 days

54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 68 | 69 | 70 | '; 71 | $i++; 72 | } 73 | ?> 74 | 75 |
Dateconcurrent connections
'.$v[0].''.number_format($v[2]).'
76 | 77 | 82 |

Concurrent Connections

83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 98 | 99 | 100 | 101 | '; 102 | $i++; 103 | } 104 | ?> 105 | 106 |
DateStream nameconcurrent connections
'.$v[0].''.$v[1].''.number_format($v[2]).'
107 | 108 |
109 | 110 |

Details:

111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 126 | 127 | 128 | 129 | '; 130 | $i++; 131 | } 132 | ?> 133 | 134 |
DateStream namenumber of seconds this stream was active
'.$v[0].''.$v[1].''.number_format($v[2]).'
135 | 136 | 137 | 140 | 141 | 144 | 145 | 146 | 147 | 244 | 245 | -------------------------------------------------------------------------------- /webroot/css/style.css: -------------------------------------------------------------------------------- 1 | /* $Id: style.css 5 2009-09-16 19:55:59Z bvamos $ */ 2 | 3 | body, td, th { 4 | font-family: Verdana; 5 | font-size: 12px; 6 | } 7 | 8 | #footer{ 9 | border-top: 1px dotted #ADADAD; 10 | padding-top: 10px; 11 | text-align: right; 12 | } 13 | 14 | th { 15 | background-color: #EDEDED; 16 | border-top: 1px solid #AAAAAA; 17 | border-bottom: 1px solid #AAAAAA; 18 | padding-right: 5px; 19 | } 20 | 21 | td.odd { 22 | background-color: #EFEFEF; 23 | } 24 | 25 | .menu1 li { 26 | padding-top: 5px; 27 | padding-bottom: 5px; 28 | } 29 | 30 | .menu1 { 31 | list-style: none; 32 | list-style-position: inside; 33 | padding-left: 0px; 34 | margin-left: 0px; 35 | } 36 | 37 | .menu2 { 38 | padding-left: 5px; 39 | margin-left: 5px; 40 | } 41 | 42 | -------------------------------------------------------------------------------- /webroot/data/bandwidth-by-time-line.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | 16 | // Database connection 17 | $db_username = $CONFIG->items['Database']['Username']; 18 | $db_password = $CONFIG->items['Database']['Password']; 19 | $db_host = $CONFIG->items['Database']['Server']; 20 | $db_database = $CONFIG->items['Database']['Database']; 21 | 22 | $DB = mysql_connect($db_host, $db_username, $db_password); 23 | mysql_select_db($db_database, $DB); 24 | 25 | // Fill initial data 26 | $start = strtotime($from_date); 27 | $end = strtotime($to_date); 28 | $intervallum = $end-$start; 29 | if($intervallum<=3600*24){ 30 | // Less than 1 days 31 | $step = 60; 32 | $dateformat_php = 'Y-m-d H:i'; 33 | $dateformat_mysql = '%Y-%m-%d %H:%i'; 34 | $x_step = 30; 35 | $title = '1 minute average'; 36 | }elseif($intervallum<=3600*24*7){ 37 | // Less than 1 week 38 | $step = 3600; 39 | $dateformat_php = 'Y-m-d H'; 40 | $dateformat_mysql = '%Y-%m-%d %H'; 41 | $x_step = 4; 42 | $title = '1 hour average'; 43 | }elseif($intervallum<=3600*24*60){ 44 | // Less than 2 months 45 | $step = 3600*24; 46 | $dateformat_php = 'Y-m-d'; 47 | $dateformat_mysql = '%Y-%m-%d'; 48 | $x_step = 2; 49 | $title = '1 day average'; 50 | }else{ 51 | // More than 2 months 52 | $step = 3600*24*30; 53 | $dateformat_php = 'Y-m'; 54 | $dateformat_mysql = '%Y-%m-01'; 55 | $x_step = 1; 56 | $title = '1 month average'; 57 | } 58 | 59 | $cur = $start; 60 | while($cur<$end){ 61 | $data[$cur] = 0; 62 | $cur += $step; 63 | } 64 | 65 | $query = "SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(`connect-timestamp`, '$dateformat_mysql')) t, 66 | SUM(ROUND(`sc-stream-bytes`/1024*8/`x-duration`, 0))/$step bw 67 | FROM fmslog 68 | WHERE FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 69 | AND `sc-stream-bytes`>0 70 | GROUP BY t;"; 71 | $result = mysql_query($query); 72 | if (!$result) { 73 | $message = 'Invalid query: ' . mysql_error() . "\n"; 74 | $message .= 'Whole query: ' . $query; 75 | die($message); 76 | } 77 | 78 | $ymax = 0; 79 | while ($row = mysql_fetch_assoc($result)) { 80 | $data[$row['t']] = (int) $row['bw']; 81 | if((int) $row['bw']>$ymax) $ymax = (int) $row['bw']; 82 | } 83 | 84 | foreach($data as $k=>$v){ 85 | $yvalues[] = new scatter_value($k, $v); 86 | $xvalues[] = $k; 87 | } 88 | 89 | $charttitle = new title( "Bandwidth - $title ($from_date - $to_date)" ); 90 | 91 | $dot = new hollow_dot(); 92 | $dot->size(0); 93 | $dot->halo_size(0); 94 | $dot->tooltip("#date:$dateformat_php#
Value: #val# Kbit/sec"); 95 | 96 | $area = new area(); 97 | $area->set_width( 2 ); 98 | $area->set_default_dot_style($dot); 99 | $area->set_colour( '#C4B86A' ); 100 | $area->set_fill_colour( '#C4B86A' ); 101 | $area->set_fill_alpha( 0.7 ); 102 | $area->set_values( $yvalues ); 103 | 104 | $chart = new open_flash_chart(); 105 | $chart->set_title( $charttitle ); 106 | $chart->add_element( $area ); 107 | 108 | $y = new y_axis(); 109 | $y->set_range( 0, pow(10, floor(log10($ymax))) * ((int)substr($ymax, 0,1)+1) ); 110 | $chart->set_y_axis( $y ); 111 | 112 | $x_labels = new x_axis_labels(); 113 | $x_labels->text("#date:$dateformat_php#"); 114 | $x_labels->rotate(270); 115 | $x_labels->set_steps( $step ); 116 | $x_labels->visible_steps($x_step); 117 | 118 | $x = new x_axis(); 119 | $x->set_labels($x_labels); 120 | $x->set_range($start, $end); 121 | $x->set_steps( $step ); 122 | 123 | $chart->set_x_axis($x); 124 | 125 | echo $chart->toString(); 126 | ?> 127 | -------------------------------------------------------------------------------- /webroot/data/hits-by-country-bar.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | 16 | // Database connection 17 | $db_username = $CONFIG->items['Database']['Username']; 18 | $db_password = $CONFIG->items['Database']['Password']; 19 | $db_host = $CONFIG->items['Database']['Server']; 20 | $db_database = $CONFIG->items['Database']['Database']; 21 | 22 | $DB = mysql_connect($db_host, $db_username, $db_password); 23 | mysql_select_db($db_database, $DB); 24 | 25 | $query = "SELECT IFNULL(NULLIF(`c-ip-country`, ''), 'Unknown') country, COUNT(*) cnt FROM fmslog 26 | WHERE FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 27 | GROUP BY country 28 | ORDER BY cnt DESC 29 | LIMIT 10;"; 30 | $result = mysql_query($query); 31 | if (!$result) { 32 | $message = 'Invalid query: ' . mysql_error() . "\n"; 33 | $message .= 'Whole query: ' . $query; 34 | die($message); 35 | } 36 | 37 | $ymax = 0; 38 | while ($row = mysql_fetch_assoc($result)) { 39 | $yvalues[] = (int) $row['cnt']; 40 | if((int) $row['cnt']>$ymax) $ymax = (int) $row['cnt']; 41 | $xvalues[] = $row['country']; 42 | } 43 | 44 | $title = new title( 'Hits by Country - TOP 10 ('.$from_date.' - '.$to_date.')' ); 45 | 46 | $bar = new bar(); 47 | $bar->set_values( $yvalues ); 48 | 49 | $chart = new open_flash_chart(); 50 | $chart->set_title( $title ); 51 | $chart->add_element( $bar ); 52 | 53 | $y = new y_axis(); 54 | $y->set_range( 0, pow(10, floor(log10($ymax))) * ((int)substr($ymax, 0,1)+1)); 55 | $chart->set_y_axis( $y ); 56 | 57 | $x_labels = new x_axis_labels(); 58 | $x_labels->set_vertical(); 59 | $x_labels->set_labels( $xvalues ); 60 | 61 | $x = new x_axis(); 62 | $x->set_labels($x_labels); 63 | $chart->set_x_axis($x); 64 | 65 | echo $chart->toString(); 66 | 67 | 68 | ?> 69 | -------------------------------------------------------------------------------- /webroot/data/hits-by-country-pie.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | 16 | // Database connection 17 | $db_username = $CONFIG->items['Database']['Username']; 18 | $db_password = $CONFIG->items['Database']['Password']; 19 | $db_host = $CONFIG->items['Database']['Server']; 20 | $db_database = $CONFIG->items['Database']['Database']; 21 | 22 | $DB = mysql_connect($db_host, $db_username, $db_password); 23 | mysql_select_db($db_database, $DB); 24 | 25 | $query = "SELECT IFNULL(NULLIF(`c-ip-country`, ''), 'Unknown') country, COUNT(*) cnt FROM fmslog 26 | WHERE FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 27 | GROUP BY country 28 | ORDER BY cnt DESC 29 | LIMIT 10;"; 30 | $result = mysql_query($query); 31 | if (!$result) { 32 | $message = 'Invalid query: ' . mysql_error() . "\n"; 33 | $message .= 'Whole query: ' . $query; 34 | die($message); 35 | } 36 | 37 | $ymax = 0; 38 | while ($row = mysql_fetch_assoc($result)) { 39 | $yvalues[] = new pie_value((int) $row['cnt'], $row['country']); 40 | if((int) $row['cnt']>$ymax) $ymax = (int) $row['cnt']; 41 | $xvalues[] = $row['country']; 42 | } 43 | 44 | $title = new title( 'Hits by Country - TOP 10 ('.$from_date.' - '.$to_date.')' ); 45 | //$title->set_style('font-size: 12px; font-weight: bold;'); 46 | 47 | 48 | $pie = new pie(); 49 | $pie->set_values( $yvalues ); 50 | $pie->set_tooltip('#val# of #total# (#percent#)'); 51 | 52 | $chart = new open_flash_chart(); 53 | $chart->set_title( $title ); 54 | $chart->add_element( $pie ); 55 | 56 | echo $chart->toString(); 57 | 58 | 59 | ?> 60 | -------------------------------------------------------------------------------- /webroot/data/hits-by-day-bar.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | $field = $params[2]; 16 | 17 | // Database connection 18 | $db_username = $CONFIG->items['Database']['Username']; 19 | $db_password = $CONFIG->items['Database']['Password']; 20 | $db_host = $CONFIG->items['Database']['Server']; 21 | $db_database = $CONFIG->items['Database']['Database']; 22 | 23 | $DB = mysql_connect($db_host, $db_username, $db_password); 24 | mysql_select_db($db_database, $DB); 25 | 26 | $query = "SELECT FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d') t, COUNT(*) cnt, 27 | AVG(`x-duration`) duration, SUM(`sc-stream-bytes`)*8/1024/SUM(`x-duration`) avgbandwidth, SUM(`sc-stream-bytes`)/1024/104 traffic_mbyte FROM fmslog 28 | WHERE `connect-timestamp`>0 29 | AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 30 | GROUP BY t ORDER BY t;"; 31 | 32 | $result = mysql_query($query); 33 | if (!$result) { 34 | $message = 'Invalid query: ' . mysql_error() . "\n"; 35 | $message .= 'Whole query: ' . $query; 36 | die($message); 37 | } 38 | 39 | $ymax = 0; 40 | while ($row = mysql_fetch_assoc($result)) { 41 | switch($field){ 42 | case 'traffic': 43 | $yvalues[] = (double) $row['traffic_mbyte']; 44 | if((double) $row['traffic_mbyte']>$ymax) $ymax = (double) $row['traffic_mbyte']; 45 | $title = 'Traffic by Day (MBytes)'; 46 | break; 47 | default: 48 | $yvalues[] = (int) $row['cnt']; 49 | if((int) $row['cnt']>$ymax) $ymax = (int) $row['cnt']; 50 | $title = 'Hits by Day'; 51 | } 52 | $xvalues[] = $row['t']; 53 | } 54 | 55 | $title = new title( $title.' ('.$from_date.' - '.$to_date.')' ); 56 | 57 | $bar = new bar(); 58 | $bar->set_values( $yvalues ); 59 | 60 | $chart = new open_flash_chart(); 61 | $chart->set_title( $title ); 62 | $chart->add_element( $bar ); 63 | 64 | $y = new y_axis(); 65 | $y->set_range( 0, pow(10, floor(log10($ymax))) * ((int)substr($ymax, 0,1)+1)); 66 | $chart->set_y_axis( $y ); 67 | 68 | $x_labels = new x_axis_labels(); 69 | $x_labels->set_vertical(); 70 | $x_labels->set_labels( $xvalues ); 71 | 72 | $x = new x_axis(); 73 | $x->set_labels($x_labels); 74 | $chart->set_x_axis($x); 75 | 76 | echo $chart->toString(); 77 | 78 | 79 | ?> 80 | -------------------------------------------------------------------------------- /webroot/data/hits-by-month-bar.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | $field = $params[2]; 16 | 17 | // Database connection 18 | $db_username = $CONFIG->items['Database']['Username']; 19 | $db_password = $CONFIG->items['Database']['Password']; 20 | $db_host = $CONFIG->items['Database']['Server']; 21 | $db_database = $CONFIG->items['Database']['Database']; 22 | 23 | $DB = mysql_connect($db_host, $db_username, $db_password); 24 | mysql_select_db($db_database, $DB); 25 | 26 | $query = "SELECT FROM_UNIXTIME(`connect-timestamp`, '%Y-%m') t, COUNT(*) cnt, 27 | AVG(`x-duration`) duration, SUM(`sc-stream-bytes`)*8/1024/SUM(`x-duration`) avgbandwidth, SUM(`sc-stream-bytes`)/1024/104 traffic_mbyte FROM fmslog 28 | WHERE `connect-timestamp`>0 29 | AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 30 | GROUP BY t ORDER BY t;"; 31 | 32 | $result = mysql_query($query); 33 | if (!$result) { 34 | $message = 'Invalid query: ' . mysql_error() . "\n"; 35 | $message .= 'Whole query: ' . $query; 36 | die($message); 37 | } 38 | 39 | $ymax = 0; 40 | while ($row = mysql_fetch_assoc($result)) { 41 | switch($field){ 42 | case 'traffic': 43 | $yvalues[] = (double) $row['traffic_mbyte']; 44 | if((double) $row['traffic_mbyte']>$ymax) $ymax = (double) $row['traffic_mbyte']; 45 | $title = 'Traffic by Month (MBytes)'; 46 | break; 47 | default: 48 | $yvalues[] = (int) $row['cnt']; 49 | if((int) $row['cnt']>$ymax) $ymax = (int) $row['cnt']; 50 | $title = 'Hits by Month'; 51 | } 52 | $xvalues[] = $row['t']; 53 | } 54 | 55 | $title = new title( $title.' ('.$from_date.' - '.$to_date.')' ); 56 | 57 | $bar = new bar(); 58 | $bar->set_values( $yvalues ); 59 | 60 | $chart = new open_flash_chart(); 61 | $chart->set_title( $title ); 62 | $chart->add_element( $bar ); 63 | 64 | $y = new y_axis(); 65 | $y->set_range( 0, pow(10, floor(log10($ymax))) * ((int)substr($ymax, 0,1)+1)); 66 | $chart->set_y_axis( $y ); 67 | 68 | $x_labels = new x_axis_labels(); 69 | $x_labels->set_vertical(); 70 | $x_labels->set_labels( $xvalues ); 71 | 72 | $x = new x_axis(); 73 | $x->set_labels($x_labels); 74 | $chart->set_x_axis($x); 75 | 76 | echo $chart->toString(); 77 | 78 | 79 | ?> 80 | -------------------------------------------------------------------------------- /webroot/data/peakbandwidth-by-time-line.php: -------------------------------------------------------------------------------- 1 | error_msg()) die($CONFIG->error_msg()); 10 | 11 | // Parameters 12 | $params = explode(';', $_GET['params']); 13 | $from_date = $params[0]; 14 | $to_date = $params[1]; 15 | 16 | // Database connection 17 | $db_username = $CONFIG->items['Database']['Username']; 18 | $db_password = $CONFIG->items['Database']['Password']; 19 | $db_host = $CONFIG->items['Database']['Server']; 20 | $db_database = $CONFIG->items['Database']['Database']; 21 | 22 | $DB = mysql_connect($db_host, $db_username, $db_password); 23 | mysql_select_db($db_database, $DB); 24 | 25 | // Fill initial data 26 | $start = strtotime($from_date); 27 | $end = strtotime($to_date); 28 | $intervallum = $end-$start; 29 | if($intervallum<=3600*24){ 30 | // Less than 1 days 31 | $step = 60; 32 | $dateformat_php = 'Y-m-d H:i'; 33 | $dateformat_mysql = '%Y-%m-%d %H:%i'; 34 | $x_step = 30; 35 | $title = '1 minute maximum'; 36 | }elseif($intervallum<=3600*24*7){ 37 | // Less than 1 week 38 | $step = 3600; 39 | $dateformat_php = 'Y-m-d H'; 40 | $dateformat_mysql = '%Y-%m-%d %H'; 41 | $x_step = 4; 42 | $title = '1 hour maximum'; 43 | }elseif($intervallum<=3600*24*60){ 44 | // Less than 2 months 45 | $step = 3600*24; 46 | $dateformat_php = 'Y-m-d'; 47 | $dateformat_mysql = '%Y-%m-%d'; 48 | $x_step = 2; 49 | $title = '1 day average'; 50 | }else{ 51 | // More than 2 months 52 | $step = 3600*24*30; 53 | $dateformat_php = 'Y-m'; 54 | $dateformat_mysql = '%Y-%m-01'; 55 | $x_step = 1; 56 | $title = '1 month average'; 57 | } 58 | 59 | $cur = $start; 60 | while($cur<$end){ 61 | $data[$cur] = 0; 62 | $cur += $step; 63 | } 64 | 65 | $query = "SELECT UNIX_TIMESTAMP(FROM_UNIXTIME(`connect-timestamp`, '$dateformat_mysql')) t, 66 | MAX(ROUND(`sc-stream-bytes`/1024*8/`x-duration`, 0)) peakbw 67 | FROM fmslog 68 | WHERE FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')>='$from_date' AND FROM_UNIXTIME(`connect-timestamp`, '%Y-%m-%d')<'$to_date' 69 | AND `sc-stream-bytes`>0 70 | GROUP BY t;"; 71 | $result = mysql_query($query); 72 | if (!$result) { 73 | $message = 'Invalid query: ' . mysql_error() . "\n"; 74 | $message .= 'Whole query: ' . $query; 75 | die($message); 76 | } 77 | 78 | $ymax = 0; 79 | while ($row = mysql_fetch_assoc($result)) { 80 | $data[$row['t']] = (int) $row['peakbw']; 81 | if((int) $row['peakbw']>$ymax) $ymax = (int) $row['peakbw']; 82 | } 83 | 84 | foreach($data as $k=>$v){ 85 | $yvalues[] = new scatter_value($k, $v); 86 | $xvalues[] = $k; 87 | } 88 | 89 | $charttitle = new title( "Peak Bandwidth - $title ($from_date - $to_date)" ); 90 | 91 | $dot = new hollow_dot(); 92 | $dot->size(0); 93 | $dot->halo_size(0); 94 | $dot->tooltip("#date:$dateformat_php#
Value: #val# Kbit/sec"); 95 | 96 | $area = new area(); 97 | $area->set_width( 2 ); 98 | $area->set_default_dot_style($dot); 99 | $area->set_colour( '#C4B86A' ); 100 | $area->set_fill_colour( '#C4B86A' ); 101 | $area->set_fill_alpha( 0.7 ); 102 | $area->set_values( $yvalues ); 103 | 104 | $chart = new open_flash_chart(); 105 | $chart->set_title( $charttitle ); 106 | $chart->add_element( $area ); 107 | 108 | $y = new y_axis(); 109 | $y->set_range( 0, pow(10, floor(log10($ymax))) * ((int)substr($ymax, 0,1)+1) ); 110 | $chart->set_y_axis( $y ); 111 | 112 | $x_labels = new x_axis_labels(); 113 | $x_labels->text("#date:$dateformat_php#"); 114 | $x_labels->rotate(270); 115 | $x_labels->set_steps( $step ); 116 | $x_labels->visible_steps($x_step); 117 | 118 | $x = new x_axis(); 119 | $x->set_labels($x_labels); 120 | $x->set_range($start, $end); 121 | $x->set_steps( $step ); 122 | 123 | $chart->set_x_axis($x); 124 | 125 | echo $chart->toString(); 126 | ?> 127 | -------------------------------------------------------------------------------- /webroot/index.php: -------------------------------------------------------------------------------- 1 | error_msg()) 7 | die($CONFIG->error_msg()); 8 | 9 | 10 | // Database connection 11 | $db_username = $CONFIG->items['Database']['Username']; 12 | $db_password = $CONFIG->items['Database']['Password']; 13 | $db_host = $CONFIG->items['Database']['Server']; 14 | $db_database = $CONFIG->items['Database']['Database']; 15 | 16 | $DB = new mysqli($db_host, $db_username, $db_password, $db_database); 17 | if ($DB->connect_error) { 18 | die('Connect Error (' . $mysqli->connect_errno . ') ' 19 | . $mysqli->connect_error); 20 | } 21 | 22 | // Check date parameters 23 | $from_date = isset($_GET['from_date']) ? $_GET['from_date'] : date('Y-m-d', strtotime('-30 day')); 24 | if (!checkdate(substr($from_date, 5, 2), substr($from_date, 8, 2), substr($from_date, 0, 4))) 25 | $from_date = date('Y-m-d', strtotime('-30 day')); 26 | $to_date = isset($_GET['to_date']) ? $_GET['to_date'] : date('Y-m-d H:m:s'); 27 | if (!checkdate(substr($to_date, 5, 2), substr($to_date, 8, 2), substr($to_date, 0, 4))) 28 | $to_date = date('Y-m-d H:m:s'); 29 | if (strtotime($to_date) - strtotime($from_date) > 3600 * 24 * 365) { 30 | die("ERROR: Time period can not be larger the 1 year."); 31 | } 32 | 33 | // Summary stats 34 | $SummaryStats = array(); 35 | $SummaryStats['hits'] = summary_stats_hits($from_date, $to_date); 36 | $SummaryStats['uniqueip'] = summary_stats_uniqueip($from_date, $to_date); 37 | $SummaryStats['uniquecountry'] = summary_stats_uniquecountry($from_date, $to_date); 38 | $SummaryStats['duration'] = summary_stats_duration($from_date, $to_date); 39 | ?> 40 | 42 | 43 | 44 | 45 | FMS Access Log Statistics 46 | 47 | 48 | 58 | 59 | 60 | 66 | 67 |

FMS Access Log Statistics - items['Common']['Sitename']; ?>

68 |

Time period: 69 | | Page generated:

70 | 71 | 72 | 73 | 119 | 240 | 241 |
74 | 75 | 76 | 97 | 98 |

 

99 | 100 |
101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 113 | 114 |
From:
to:
112 |
115 |
116 | 117 | 118 |
120 | 121 | 122 |

Summary Stats

123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 |
Hits:
Unique IPs:
Unique Countries:
Duration in sec (Sum/Max/Min):
141 | 142 |

Access stats

143 | 144 |

TOP 20 streams

145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | '; 163 | print ' 164 | 165 | 166 | 167 | 168 | 169 | '; 170 | $i++; 171 | } 172 | ?> 173 | 174 |
StreamHitsTraffic (MByte)Average duration (Sec)Average bandwidth (Kbit/sec)
175 |
[+/-] Show all/Show TOP 20 176 | 177 |

Visitor stats

178 | 179 |

Hits by Country

180 |
181 |
182 | 183 |

TOP 20 Unique IPs

184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | '; 202 | print ' 203 | 204 | 205 | 206 | 207 | 208 | '; 209 | $i++; 210 | } 211 | ?> 212 | 213 |
Client IPHitsTraffic (MByte)Average duration (Sec)Average bandwidth (Kbit/sec)
214 |
[+/-] Show all/Show TOP 20 215 | 216 | 217 |

Activity stats

218 | 219 |

Daily Hits

220 |
221 | 222 |

Daily Traffic

223 |
224 | 225 |

Monthly Hits

226 |
227 | 228 |

Monthly Traffic

229 |
230 | 231 |

Bandwidth

232 |
233 | 234 |

Peak Bandwidth

235 |
236 | 237 | 238 | 239 |
242 | 243 | 246 | 247 | 248 | 249 | query($query); 258 | 259 | if (!$result) { 260 | $message = 'Invalid query: ' . $DB->error . "\n"; 261 | $message .= 'Whole query: ' . $query; 262 | die($message); 263 | } else { 264 | $resultoutput = $result->fetch_assoc(); 265 | } 266 | $result->close(); 267 | 268 | return $resultoutput['cnt']; 269 | } 270 | 271 | function summary_stats_uniqueip($from_date, $to_date) { 272 | global $DB; 273 | 274 | $query = "SELECT DISTINCT `c-client-id` " 275 | . "FROM connections " 276 | . "WHERE `timestamp-start` " 277 | . "BETWEEN '" . $from_date . "' AND '" . $to_date . "' " 278 | . "AND `c-ip`!='-'"; 279 | $result = $DB->query($query); 280 | if (!$result) { 281 | $message = 'Invalid query: ' . $DB->error . "\n"; 282 | $message .= 'Whole query: ' . $query; 283 | die($message); 284 | } else { 285 | $resultoutput = $result->num_rows; 286 | } 287 | $result->close(); 288 | 289 | return $resultoutput; 290 | } 291 | 292 | function summary_stats_uniquecountry($from_date, $to_date) { 293 | global $DB; 294 | 295 | $query = "SELECT DISTINCT `c-ip-country` " 296 | . "FROM connections " 297 | . "WHERE `timestamp-start` " 298 | . "BETWEEN '" . $from_date . "' AND '" . $to_date . "' "; 299 | $result = $DB->query($query); 300 | if (!$result) { 301 | $message = 'Invalid query: ' . $DB->error . "\n"; 302 | $message .= 'Whole query: ' . $query; 303 | die($message); 304 | } else { 305 | $resultoutput = $result->num_rows; 306 | } 307 | $result->close(); 308 | 309 | return $resultoutput; 310 | } 311 | 312 | function summary_stats_allfiles($from_date, $to_date, $limit = 20) { 313 | global $DB; 314 | 315 | $query = "SELECT `streamname`, " 316 | . "COUNT(*) cnt, " 317 | . "ROUND(SUM(`bytes`)/1024/104, 0) AS traffic_mbyte, " 318 | . "ROUND(AVG(`duration`), 0) AS avgduration, " 319 | . "ROUND(SUM(`bytes`)*8/1024/SUM(`duration`), 0) AS avgbandwidth " 320 | . "FROM connections " 321 | . "WHERE `streamname`!='-' " 322 | . "AND `timestamp-start` " 323 | . "BETWEEN '" . $from_date . "' AND '" . $to_date . "' " 324 | . "GROUP BY `streamname` " 325 | . "ORDER BY cnt DESC " 326 | . "LIMIT " . $limit; 327 | $result = $DB->query($query); 328 | if (!$result) { 329 | $message = 'Invalid query: ' . $DB->error . "\n"; 330 | $message .= 'Whole query: ' . $query; 331 | die($message); 332 | } else { 333 | 334 | $ret = array(); 335 | if ($result->num_rows == 0) { 336 | $resultoutput = $ret; 337 | } 338 | 339 | while ($row = $result->fetch_array()) { 340 | $ret[] = $row; 341 | } 342 | 343 | $resultoutput = $ret; 344 | } 345 | $result->close(); 346 | 347 | return $resultoutput; 348 | } 349 | 350 | function summary_stats_uniqueip_list($from_date, $to_date, $limit = 20) { 351 | global $DB; 352 | 353 | $query = "SELECT `c-ip`, " 354 | . "COUNT(*) cnt, " 355 | . "ROUND(SUM(`bytes`)/1024/104, 0) AS traffic_mbyte, " 356 | . "ROUND(AVG(`duration`), 0) AS avgduration, " 357 | . "ROUND(SUM(`bytes`)*8/1024/SUM(`duration`), 0) AS avgbandwidth " 358 | . "FROM connections " 359 | . "WHERE `c-ip`!='-' " 360 | . "AND `timestamp-start` " 361 | . "BETWEEN '" . $from_date . "' AND '" . $to_date . "' " 362 | . "GROUP BY `c-ip` " 363 | . "ORDER BY cnt DESC " 364 | . "LIMIT " . $limit; 365 | $result = $DB->query($query); 366 | if (!$result) { 367 | $message = 'Invalid query: ' . mysql_error() . "\n"; 368 | $message .= 'Whole query: ' . $query; 369 | die($message); 370 | } else { 371 | 372 | $ret = array(); 373 | if ($result->num_rows == 0) { 374 | $resultoutput = $ret; 375 | } 376 | 377 | while ($row = $result->fetch_array()) { 378 | $ret[] = $row; 379 | } 380 | 381 | $resultoutput = $ret; 382 | } 383 | $result->close(); 384 | 385 | return $resultoutput; 386 | } 387 | 388 | function summary_stats_duration($from_date, $to_date) { 389 | global $DB; 390 | 391 | $query = "SELECT SUM(`duration`) sumdur, " 392 | . "MAX(`duration`) maxdur, " 393 | . "MIN(`duration`) mindur " 394 | . "FROM connections " 395 | . "WHERE `timestamp-start` " 396 | . "BETWEEN '" . $from_date . "' AND '" . $to_date . "' "; 397 | $result = $DB->query($query); 398 | if (!$result) { 399 | $message = 'Invalid query: ' . mysql_error() . "\n"; 400 | $message .= 'Whole query: ' . $query; 401 | die($message); 402 | } else { 403 | $resultoutput = $result->fetch_assoc(); 404 | } 405 | $result->close(); 406 | 407 | return array('sumdur' => $resultoutput['sumdur'], 408 | 'maxdur' => $resultoutput['maxdur'], 409 | 'mindur' => $resultoutput['mindur'] 410 | ); 411 | } 412 | ?> 413 | -------------------------------------------------------------------------------- /webroot/js/swfobject/expressInstall.swf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/openHPI/nginx-hls-analyzer/3bdcba05b6a8fd25f386f77c4da2f74506164ccb/webroot/js/swfobject/expressInstall.swf -------------------------------------------------------------------------------- /webroot/js/swfobject/swfobject.js: -------------------------------------------------------------------------------- 1 | /* SWFObject v2.2 2 | is released under the MIT License 3 | */ 4 | var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y0){for(var af=0;af0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad'}}aa.outerHTML='"+af+"";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab