├── .gitignore ├── README.md ├── UPDATING.txt ├── admin ├── index.php ├── login.php ├── require_login.php ├── template.php └── update.php ├── atom2rss ├── atom2atom.xsl ├── atom2rss.xsl └── index.php ├── cache ├── .gitignore ├── http-responses │ └── .gitignore └── rss │ └── .gitignore ├── changelog.txt ├── cleancache.php ├── config.php ├── css ├── bootstrap.min.css ├── feed.css └── feed.xsl ├── feed_reformator.php ├── ftr_compatibility_test.php ├── images └── agplv3.png ├── index.php ├── js ├── bootstrap-popover.js ├── bootstrap-tab.js ├── bootstrap-tooltip.js └── jquery.min.js ├── libraries ├── Zend │ ├── Cache.php │ ├── Cache │ │ ├── Backend.php │ │ ├── Backend │ │ │ ├── Apc.php │ │ │ ├── BlackHole.php │ │ │ ├── ExtendedInterface.php │ │ │ ├── File.php │ │ │ ├── Interface.php │ │ │ ├── Memcached.php │ │ │ ├── Sqlite.php │ │ │ ├── Static.php │ │ │ ├── Test.php │ │ │ ├── TwoLevels.php │ │ │ ├── Xcache.php │ │ │ ├── ZendPlatform.php │ │ │ ├── ZendServer.php │ │ │ └── ZendServer │ │ │ │ ├── Disk.php │ │ │ │ └── ShMem.php │ │ ├── Core.php │ │ ├── Exception.php │ │ ├── Frontend │ │ │ ├── Capture.php │ │ │ ├── Class.php │ │ │ ├── File.php │ │ │ ├── Function.php │ │ │ ├── Output.php │ │ │ └── Page.php │ │ └── Manager.php │ ├── Dom │ │ └── Query │ │ │ └── Css2Xpath.php │ ├── Exception.php │ └── Loader.php ├── content-extractor │ ├── ContentExtractor.php │ ├── SiteConfig.php │ └── simple_html_dom.php ├── feedwriter │ ├── FeedItem.php │ └── FeedWriter.php ├── humble-http-agent │ ├── CookieJar.php │ ├── HumbleHttpAgent.php │ ├── RollingCurl.php │ └── SimplePie_HumbleHttpAgent.php ├── language-detect │ ├── LanguageDetect.php │ ├── Parser.php │ ├── lang.dat │ └── unicode_blocks.dat ├── phantomjs-2.1.1-linux-i686 │ ├── ChangeLog │ ├── LICENSE.BSD │ ├── README.md │ ├── bin │ │ ├── jquery.js │ │ ├── phantomjs-exec.js │ │ └── test.sh │ ├── examples │ │ ├── arguments.js │ │ ├── child_process-examples.js │ │ ├── colorwheel.js │ │ ├── countdown.js │ │ ├── detectsniff.js │ │ ├── echoToFile.js │ │ ├── features.js │ │ ├── fibo.js │ │ ├── hello.js │ │ ├── injectme.js │ │ ├── loadspeed.js │ │ ├── loadurlwithoutcss.js │ │ ├── modernizr.js │ │ ├── module.js │ │ ├── netlog.js │ │ ├── netsniff.js │ │ ├── openurlwithproxy.js │ │ ├── outputEncoding.js │ │ ├── page_events.js │ │ ├── pagecallback.js │ │ ├── phantomwebintro.js │ │ ├── post.js │ │ ├── postjson.js │ │ ├── postserver.js │ │ ├── printenv.js │ │ ├── printheaderfooter.js │ │ ├── printmargins.js │ │ ├── rasterize.js │ │ ├── render_multi_url.js │ │ ├── responsive-screenshot.js │ │ ├── run-jasmine.js │ │ ├── run-jasmine2.js │ │ ├── run-qunit.js │ │ ├── scandir.js │ │ ├── server.js │ │ ├── serverkeepalive.js │ │ ├── simpleserver.js │ │ ├── sleepsort.js │ │ ├── stdin-stdout-stderr.js │ │ ├── universe.js │ │ ├── unrandomize.js │ │ ├── useragent.js │ │ ├── version.js │ │ ├── waitfor.js │ │ └── walk_through_frames.js │ └── third-party.txt ├── readability │ ├── JSLikeHTMLElement.php │ └── Readability.php └── simplepie │ ├── LICENSE.txt │ ├── SimplePie.php │ ├── SimplePie │ ├── Author.php │ ├── Cache.php │ ├── Cache │ │ ├── Base.php │ │ ├── DB.php │ │ ├── File.php │ │ ├── Memcache.php │ │ └── MySQL.php │ ├── Caption.php │ ├── Category.php │ ├── Content │ │ └── Type │ │ │ └── Sniffer.php │ ├── Copyright.php │ ├── Core.php │ ├── Credit.php │ ├── Decode │ │ └── HTML │ │ │ └── Entities.php │ ├── Enclosure.php │ ├── File.php │ ├── HTTP │ │ └── Parser.php │ ├── IRI.php │ ├── Item.php │ ├── Locator.php │ ├── Misc.php │ ├── Net │ │ └── IPv6.php │ ├── Parse │ │ └── Date.php │ ├── Parser.php │ ├── Rating.php │ ├── Restriction.php │ ├── Sanitize.php │ ├── Source.php │ ├── XML │ │ └── Declaration │ │ │ └── Parser.php │ └── gzdecode.php │ └── SimplePieAutoloader.php ├── license.txt ├── makefulltextfeed.php └── site_config ├── README.txt ├── custom └── index.php ├── description_filter_description.php ├── description_filter_lib.php ├── description_filter_title.php ├── filter_permalink.php ├── filter_skip_item.php ├── index.php ├── permalink_blacklist.php ├── standard ├── .wikipedia.org.txt ├── appguru.com.tw.txt ├── bbs.onyx-international.com.cn.txt ├── boardgame-record.blogspot.tw.txt ├── ccsx.tw.txt ├── chinese.engadget.com.txt ├── data-sci.info.txt ├── easylife.tw.txt ├── ez3c.tw.txt ├── feed.ipc.me.txt ├── feedproxy.google.com/~r/soft4funtw/.txt ├── feeds.freegroup.org.txt ├── freegroup.org.txt ├── freewarehome.tw.txt ├── gnn.gamer.com.tw.txt ├── h9856.blogspot.com.txt ├── h9856.blogspot.tw.txt ├── hkacger.com.txt ├── incognitomail.com.txt ├── index.php ├── isvincent.pixnet.net.txt ├── libraryview.me.txt ├── linuxeden.com.txt ├── mobileai.net.txt ├── mr6.cc.txt ├── my.oschina.net.txt ├── netadmin.com.tw.txt ├── news.xfastest.com.txt ├── software.sopili.net.txt ├── sub-fju-2017.blogspot.com.txt ├── subscription-airiti-library.blogspot.tw.txt ├── tw.battle.net.txt ├── udn.com.txt ├── version.php ├── www.bnext.com.tw.txt ├── www.damanwoo.com.txt ├── www.eprice.com.tw.txt ├── www.fhm.com.tw.txt ├── www.gameapps.hk.txt ├── www.hearthpwn.com.txt ├── www.mobile01.com.txt ├── www.plurk.com.txt ├── www.raspberrypi.com.tw.txt ├── www.reddit.com.txt ├── www.sciencedirect.com.txt ├── www.soft4fun.net.txt ├── www.solidot.org.txt ├── www.techbang.com.txt ├── www.wallflux.com.txt └── www.youtube.com.txt └── template └── standard.xml.txt /.gitignore: -------------------------------------------------------------------------------- 1 | /[[]document]/ 2 | /open_webpage.bat -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Full-Text RSS 2 | ============= 3 | 4 | ### NOTE 備註 5 | 6 | This is a our public version of Full-Text RSS available to download for free from . 7 | 8 | This version has been enhanced by Pulipuli Chen with: 9 | - Multi-pages integration / 多頁面整合 10 | - Part of the interface support Traditional Chinese / 部分介面提供正體中文 11 | 12 | For best extraction results, and to help us sustain the project, you can purchase the most up-to-date version at - so if you like this free version, please consider supporting us by purchasing the latest release. 13 | 14 | If you have no need for the latest release, but would still like to contribute something, you can donate via [Gittip](https://www.gittip.com/fivefilters/) or [Flattr](https://flattr.com/profile/k1m). 15 | 16 | ### ERROR REPORT 錯誤回報 17 | 18 | If you always get RSS feed extraction fail, please report the URL of RSS feed to [GitHub Issue](https://github.com/pulipulichen/full-text-rss/issues/new). (Registation needed) 19 | / 如果RSS feed資訊來源一直無法順利抽取出全文,請回報該RSS feed資訊來源的網址到[GitHub Issue](https://github.com/pulipulichen/full-text-rss/issues/new)中(需要註冊,免費) 20 | 21 | ### About 關於 22 | 23 | See for a description of the code. 24 | 25 | ### Installation 安裝方法 26 | 27 | 1. Extract the files in [this ZIP](https://github.com/pulipulichen/full-text-rss/archive/master.zip) archive to a folder on your computer. 28 | / 請[下載壓縮檔](https://github.com/pulipulichen/full-text-rss/archive/master.zip),解壓縮到你的電腦中 29 | 30 | 2. FTP the files up to your server 31 | / 將檔案上傳到你的伺服器 32 | 33 | 3. Access index.php through your browser. E.g. http://example.org/full-text-rss/index.php 34 | / 開啟index.php網頁,例如 http://example.org/full-text-rss/index.php 35 | 36 | 4. Enter a URL in the form field to test the code 37 | / 輸入網址遞交表單,測試看能不能順利運作 38 | 39 | 5. If you get an RSS feed with full-text content, all is working well. :) 40 | / 如果網頁正常顯示全文RSS資訊來源,那就是正常運作了! :) 41 | 42 | ### Configuration (optional) 設定 (可選) 43 | 44 | 1. Save a copy of config.php as custom_config.php and edit custom_config.php 45 | 46 | 2. If you decide to enable caching, make sure the cache folder (and its 2 sub folders) is writable. (You might need to change the permissions of these folders to 777 through your FTP client.) 47 | 48 | 3. If extraction always failed, please try to increase "max_execution_time", "max_input_time", and "memory_limit" in your server's php.ini and restart server. 49 | / 如果文章抽取總是失敗,請嘗試設定php.ini的"max_execution_time"、"max_input_time"與"memory_limit",並重新啟動伺服器。 50 | 51 | ### Site-specific extraction rules 特定網站的抽取規則 52 | 53 | This free version does not contain the site config files we include with purchased copies, but these are now all available [online](https://github.com/fivefilters/ftr-site-config). If you'd like to keep yours up to date using Git, follow the steps below: 54 | 55 | 1. Change into the site_config/standard/ folder 56 | 2. Delete everything in there 57 | 3. Using the command line, enter: `git clone https://github.com/pulipulichen/full-text-rss.git .` 58 | 4. Git should now download the latest site config files for you. 59 | 5. To update the site config files again, you can simply run `git pull` from the directory. 60 | 61 | ### Code example 程式碼範例 62 | 63 | If you're developing an application which requires content extraction, you can call Full-Text RSS as a web service from within your application. Here's how to do it in PHP: 64 | 65 | rss->channel->item); 86 | 87 | $title = $json->rss->channel->item->title; 88 | // Note: this works when you're processing an article. 89 | // If the input URL is a feed, ->item will be an array. 90 | 91 | echo $title; 92 | 93 | ### Different language? 搭配其他語言 94 | 95 | Although we don't have examples in other programming languages, the essential steps should be: 96 | 97 | 1. Construct the request URL using URL where you installed Full-Text RSS and the article or feed URL (see $ftr, $article, $request in example above). 98 | 99 | 2. Fetch the resulting URL using an HTTP GET request. 100 | 101 | 3. Parse the HTTP response body as JSON and grab what you need. 102 | 103 | ### MEMO 104 | 105 | 設定偵測用的預設網址:/config.php 106 | 設定下一頁:/config.php 107 | 設定選擇範圍:/libraries/content-extractor/SiteConfig.php 108 | 109 | # OpenVZ Template 110 | debian-7-full-text-rss_i386.tar.gz 111 | https://drive.google.com/open?id=0B5UXWzdIPpm0VzJyV29GRklubkE 112 | 113 | # ATOM to RSS 114 | apt-get install php5-xsl -y 115 | /atom2rss/?atom=[URL] -------------------------------------------------------------------------------- /UPDATING.txt: -------------------------------------------------------------------------------- 1 | Updating Full-Text RSS 2 | ====================== 3 | 4 | To update your copy of Full-Text RSS to ensure feeds continue to be processed as they were before, we suggest the following steps: 5 | 6 | 1. Keep your current installation in place for now (we'll deal with it later) 7 | 8 | 2. Extract this updated package to a new folder -- for example, if the last version is in a folder called 'full-text-rss', extract this version to a new folder called 'full-text-rss-updated' 9 | 10 | 3. FTP the new folder up to your server 11 | 12 | 4. Access index.php in the new folder through your browser -- for example http://example.org/full-text-rss-updated/index.php 13 | 14 | 5. Enter a URL in the form field to test the updated code 15 | 16 | 6. If you'd configured the last version, copy custom_config.php from your old version to the new installation. 17 | 18 | 7. If you'd added custom site config files (in site_config/custom/), copy those over to the new installation. 19 | 20 | 8. Test the new copy again to make sure the config values are now applied to the new version. 21 | 22 | 9. Now simply rename the folder with your old copy to 'full-text-rss-old' and then rename the folder with the new copy to 'full-text-rss' (or whatever name you'd given the original folder). 23 | 24 | That's all that's needed. Your feeds should continue to work as they did before. Let us know if you have any trouble: help@fivefilters.org. 25 | 26 | Updating Site Patterns 27 | ====================== 28 | 29 | Site patterns are used by Full-Text RSS to improve extraction for certain sites. These are simple text files which are updated more frequently than the Full-Text RSS software itself. 30 | 31 | To make sure your copy of Full-Text RSS is using the latest site patterns, We've created a simple tool to help you get the latest copy of these site patterns from FiveFilters.org. To use it, access the admin/ folder in your browser and follow the instructions. -------------------------------------------------------------------------------- /admin/index.php: -------------------------------------------------------------------------------- 1 | . 23 | */ 24 | 25 | // Usage 26 | // ----- 27 | // Access this file in your browser 28 | 29 | error_reporting(E_ALL ^ E_NOTICE); 30 | ini_set("display_errors", 1); 31 | @set_time_limit(120); 32 | 33 | //////////////////////////////// 34 | // Load config file 35 | //////////////////////////////// 36 | require_once('../config.php'); 37 | require_once('require_login.php'); 38 | require_once('template.php'); 39 | tpl_header('Admin'); 40 | 41 | ?> 42 |

The admin pages are intended to help you manage your copy of Full-Text RSS more easily.

43 |

We currently offer an experimental update tool which you can use to update your site patterns.

-------------------------------------------------------------------------------- /admin/login.php: -------------------------------------------------------------------------------- 1 | admin_credentials) || $options->admin_credentials['username'] == '' || $options->admin_credentials['password'] == '') { 5 | die('

Admin privileges required

This page requires admin privileges but Full-Text RSS has not been configured with admin credentials.

If you are the administrator, please edit your custom_config.php file and enter the credentials in the appropriate section. When you\'ve done that, this page will prompt you for your admin credentials.

'); 6 | } 7 | 8 | $name = @$_POST['username']; 9 | $pass = @$_POST['pass']; 10 | $invalid_login = false; 11 | 12 | if ($name || $pass) { 13 | if ($name == $options->admin_credentials['username'] && $pass == $options->admin_credentials['password']) { 14 | // Authentication successful - set session 15 | $_SESSION['auth'] = 1; 16 | if (isset($_POST['redirect']) && preg_match('/^[0-9a-z]+$/', $_POST['redirect'])) { 17 | header('Location: '.$_POST['redirect'].'.php'); 18 | } else { 19 | header('Location: index.php'); 20 | } 21 | exit; 22 | } 23 | $invalid_login = true; 24 | } 25 | ?> 26 | 27 | 28 | Login 29 | 30 | Invalid login, please try again. If you can\'t remember your admin credentials, open your custom_config.php and you\'ll find them in there.

'; ?> 31 |
32 | '; ?> 33 | 34 | 35 | 36 |
37 | 38 | -------------------------------------------------------------------------------- /admin/require_login.php: -------------------------------------------------------------------------------- 1 | . 23 | */ 24 | 25 | // Usage 26 | // ----- 27 | // This file is included on pages which require admin privileges - e.g. updating the software. 28 | // The username is 'admin' by default and the password should be set in the custom_config.php file. 29 | session_start(); 30 | require_once(dirname(dirname(__FILE__)).'/config.php'); 31 | 32 | $realm = 'Restricted area'; 33 | 34 | if (isset($_GET['logout'])) $_SESSION['auth'] = 0; 35 | 36 | if (!isset($_SESSION['auth']) || $_SESSION['auth'] != 1) { 37 | if (isset($admin_page)) { 38 | header('Location: login.php?redirect='.$admin_page); 39 | } else { 40 | header('Location: login.php'); 41 | } 42 | exit; 43 | } 44 | 45 | /* HTTP DIGEST authentication - doesn't work without server tweaks in FastCGI environments 46 | 47 | //user => password 48 | $users = array($options->admin_credentials['username'] => $options->admin_credentials['password']); 49 | 50 | if (empty($_SERVER['PHP_AUTH_DIGEST'])) { 51 | header('HTTP/1.1 401 Unauthorized'); 52 | header('WWW-Authenticate: Digest realm="'.$realm. 53 | '",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"'); 54 | 55 | die('If you can\'t remember your admin credentials, open your custom_config.php and you\'ll find them in there.'); 56 | } 57 | 58 | 59 | // analyze the PHP_AUTH_DIGEST variable 60 | if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || 61 | !isset($users[$data['username']])) 62 | die('Wrong credentials!'); 63 | 64 | 65 | // generate the valid response 66 | $A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]); 67 | $A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']); 68 | $valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2); 69 | 70 | if ($data['response'] != $valid_response) 71 | die('Wrong credentials!'); 72 | 73 | // ok, valid username & password 74 | // echo 'Thanks! You are now logged in.'; 75 | unset($realm, $users, $data, $A1, $A2, $valid_response); 76 | 77 | // function to parse the http auth header 78 | function http_digest_parse($txt) 79 | { 80 | // protect against missing data 81 | $needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); 82 | $data = array(); 83 | $keys = implode('|', array_keys($needed_parts)); 84 | 85 | preg_match_all('@(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $txt, $matches, PREG_SET_ORDER); 86 | 87 | foreach ($matches as $m) { 88 | $data[$m[1]] = $m[3] ? $m[3] : $m[4]; 89 | unset($needed_parts[$m[1]]); 90 | } 91 | 92 | return $needed_parts ? false : $data; 93 | } 94 | */ 95 | ?> -------------------------------------------------------------------------------- /admin/template.php: -------------------------------------------------------------------------------- 1 | 5 | 6 | 7 | 8 | <?php echo $title; ?> 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 25 | 26 | 27 |
28 | 39 | 40 | 45 | 46 |
47 | 48 | 49 | 2 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | html 43 | 44 | 45 | 46 | xhtml 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | -------------------------------------------------------------------------------- /atom2rss/index.php: -------------------------------------------------------------------------------- 1 | load($atom); /* load channel */ 9 | $sheet = new DOMDocument(); $sheet->load('atom2rss.xsl'); /* use stylesheet from this page */ 10 | $processor = new XSLTProcessor(); 11 | $processor->registerPHPFunctions(); 12 | $processor->importStylesheet($sheet); 13 | $result = $processor->transformToXML($chan); /* transform to XML string (there are other options - see PHP manual) */ 14 | header("Content-Type: application/rss+xml; charset=utf-8"); 15 | echo $result; 16 | 17 | // http://exp-full-text-rss-2013.dlll.nccu.edu.tw/full-text-rss/atom2rss/?atom=https://www.reddit.com/r/googleplaydeals/.rss -------------------------------------------------------------------------------- /cache/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cache/http-responses/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cache/rss/.gitignore: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /cleancache.php: -------------------------------------------------------------------------------- 1 | . 20 | */ 21 | 22 | // Usage 23 | // ----- 24 | // Set up your scheduler (e.g. cron) to request this file periodically. 25 | // Note: this file must not be named cleancache.php so please rename it. 26 | // We ask you to do this to prevent others from initiating 27 | // the cache cleanup process. It will not run if it's called cleancache.php. 28 | 29 | error_reporting(E_ALL ^ E_NOTICE); 30 | ini_set("display_errors", 1); 31 | @set_time_limit(120); 32 | 33 | // check file name 34 | if (basename(__FILE__) == 'cleancache.php') die('cleancache.php must be renamed'); 35 | 36 | // set include path 37 | set_include_path(realpath(dirname(__FILE__).'/libraries').PATH_SEPARATOR.get_include_path()); 38 | 39 | // Autoloading of classes allows us to include files only when they're 40 | // needed. If we've got a cached copy, for example, only Zend_Cache is loaded. 41 | function __autoload($class_name) { 42 | static $mapping = array( 43 | 'Zend_Cache' => 'Zend/Cache.php' 44 | ); 45 | if (isset($mapping[$class_name])) { 46 | //echo "Loading $class_name\n
"; 47 | require_once $mapping[$class_name]; 48 | return true; 49 | } else { 50 | return false; 51 | } 52 | } 53 | require_once(dirname(__FILE__).'/config.php'); 54 | if (!$options->caching) die('Caching is disabled'); 55 | 56 | /* 57 | // clean http response cache 58 | $frontendOptions = array( 59 | 'lifetime' => 30*60, // cache lifetime of 30 minutes 60 | 'automatic_serialization' => true, 61 | 'write_control' => false, 62 | 'automatic_cleaning_factor' => 0, 63 | 'ignore_user_abort' => false 64 | ); 65 | $backendOptions = array( 66 | 'cache_dir' => $options->cache_dir.'/http-responses/', 67 | 'file_locking' => false, 68 | 'read_control' => true, 69 | 'read_control_type' => 'strlen', 70 | 'hashed_directory_level' => $options->cache_directory_level, 71 | 'hashed_directory_umask' => 0777, 72 | 'cache_file_umask' => 0664, 73 | 'file_name_prefix' => 'ff' 74 | ); 75 | $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); 76 | $cache->clean(Zend_Cache::CLEANING_MODE_OLD); 77 | */ 78 | 79 | // clean rss (non-key) cache 80 | $frontendOptions = array( 81 | 'lifetime' => 20*60, 82 | 'automatic_serialization' => false, 83 | 'write_control' => false, 84 | 'automatic_cleaning_factor' => 0, 85 | 'ignore_user_abort' => false 86 | ); 87 | $backendOptions = array( 88 | 'cache_dir' => $options->cache_dir.'/rss/', 89 | 'file_locking' => false, 90 | 'read_control' => true, 91 | 'read_control_type' => 'strlen', 92 | 'hashed_directory_level' => $options->cache_directory_level, 93 | 'hashed_directory_umask' => 0777, 94 | 'cache_file_umask' => 0664, 95 | 'file_name_prefix' => 'ff' 96 | ); 97 | $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); 98 | $cache->clean(Zend_Cache::CLEANING_MODE_OLD); 99 | 100 | // clean rss (key) cache 101 | $frontendOptions = array( 102 | 'lifetime' => 20*60, 103 | 'automatic_serialization' => false, 104 | 'write_control' => false, 105 | 'automatic_cleaning_factor' => 0, 106 | 'ignore_user_abort' => false 107 | ); 108 | $backendOptions = array( 109 | 'cache_dir' => $options->cache_dir.'/rss-with-key/', 110 | 'file_locking' => false, 111 | 'read_control' => true, 112 | 'read_control_type' => 'strlen', 113 | 'hashed_directory_level' => $options->cache_directory_level, 114 | 'hashed_directory_umask' => 0777, 115 | 'cache_file_umask' => 0664, 116 | 'file_name_prefix' => 'ff' 117 | ); 118 | $cache = Zend_Cache::factory('Core', 'File', $frontendOptions, $backendOptions); 119 | $cache->clean(Zend_Cache::CLEANING_MODE_OLD); 120 | 121 | ?> -------------------------------------------------------------------------------- /css/feed.css: -------------------------------------------------------------------------------- 1 | /* RSS CSS Document */ 2 | 3 | * { margin:0; padding:0; } 4 | 5 | p { padding: .5em 0; } 6 | 7 | h1,h2,h3,h4,h5,h6 { font-size: 1em; padding: .5em 0; } 8 | 9 | html { display:block; padding-bottom:50px; } 10 | body { font:80% Verdana, sans-serif; color:#000; padding:25px 0 0 35px; } 11 | 12 | a { color:#5BAB03; text-decoration:none; } 13 | a:hover { color:#5BAB03; text-decoration: underline;} 14 | 15 | ul { margin-left:1.5em; } 16 | li { margin-bottom:0.4em; } 17 | div#content>ul { list-style-type: none; } 18 | div.article>li>a { font-weight:bold; font-size: 1.3em;} 19 | 20 | 21 | div { line-height:1.6em; } 22 | 23 | div#content { background:#fff; margin-right:15px; padding-left:1em;} 24 | div#content div { margin:0 1em 1em 0; } 25 | 26 | div#explanation { padding:1em 1em 0 1em; border:1px solid #ddd; background:#efefef; margin:0 2em 2em 0; } 27 | div#explanation h1 { font-weight:normal; font-size:1.8em; margin-bottom:0.3em; } 28 | div#explanation p { margin-bottom:1em; } 29 | 30 | .small { font-size: .7em; color: #666; } -------------------------------------------------------------------------------- /css/feed.xsl: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <xsl:value-of select="$title"/> (full-text feed) 9 | 12 | 13 | 14 |
15 |

(full-text feed)

16 |

You are viewing an auto-generated full-text RSS feed. RSS feeds allow you to stay up to date with the latest news and features you want from websites. To subscribe to it, you will need a News Reader or other similar device.

17 |

Below is the latest content available from this feed.

18 | Send RSS feed url to Feedly 19 | | 20 | Back 21 |
22 | 23 |
24 |
    25 | 26 |
    27 |
  • 28 |
    29 |
  • 30 |
    31 |
    32 |
33 |
34 | 35 | 36 |
37 |
-------------------------------------------------------------------------------- /feed_reformator.php: -------------------------------------------------------------------------------- 1 | ]+(?:\([\w\d]+\)|([^,[:punct:]\s]|/))#', $string, $match); 13 | 14 | print_r($match[0][0]); 15 | exit(); 16 | */ 17 | if (isset($_GET["url"]) === false) { 18 | exit(); 19 | } 20 | 21 | $url = $_GET["url"]; 22 | $feed = file_get_contents($url); 23 | 24 | if (strpos($url, "www.fhm.com.tw") !== FALSE) { 25 | 26 | $desc_list = explode("", $feed); 27 | 28 | foreach ($desc_list AS $key => $desc_item) { 29 | if ($key === 0) { 30 | continue; 31 | } 32 | $desc_parts = explode("", $desc_item); 33 | $desc_parts[0] = htmlspecialchars($desc_parts[0]); 34 | $desc_list[$key] = $desc_parts[0] . '' . $desc_parts[1]; 35 | } 36 | $feed = implode("", $desc_list); 37 | 38 | $feed = str_replace("", "", "]]>", $feed); 40 | } 41 | 42 | echo $feed; -------------------------------------------------------------------------------- /images/agplv3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/pulipulichen/full-text-rss/HEAD/images/agplv3.png -------------------------------------------------------------------------------- /js/bootstrap-popover.js: -------------------------------------------------------------------------------- 1 | /* =========================================================== 2 | * bootstrap-popover.js v2.0.3 3 | * http://twitter.github.com/bootstrap/javascript.html#popovers 4 | * =========================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * =========================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* POPOVER PUBLIC CLASS DEFINITION 27 | * =============================== */ 28 | 29 | var Popover = function ( element, options ) { 30 | this.init('popover', element, options) 31 | } 32 | 33 | 34 | /* NOTE: POPOVER EXTENDS BOOTSTRAP-TOOLTIP.js 35 | ========================================== */ 36 | 37 | Popover.prototype = $.extend({}, $.fn.tooltip.Constructor.prototype, { 38 | 39 | constructor: Popover 40 | 41 | , setContent: function () { 42 | var $tip = this.tip() 43 | , title = this.getTitle() 44 | , content = this.getContent() 45 | 46 | $tip.find('.popover-title')[this.isHTML(title) ? 'html' : 'text'](title) 47 | $tip.find('.popover-content > *')[this.isHTML(content) ? 'html' : 'text'](content) 48 | 49 | $tip.removeClass('fade top bottom left right in') 50 | } 51 | 52 | , hasContent: function () { 53 | return this.getTitle() || this.getContent() 54 | } 55 | 56 | , getContent: function () { 57 | var content 58 | , $e = this.$element 59 | , o = this.options 60 | 61 | content = $e.attr('data-content') 62 | || (typeof o.content == 'function' ? o.content.call($e[0]) : o.content) 63 | 64 | return content 65 | } 66 | 67 | , tip: function () { 68 | if (!this.$tip) { 69 | this.$tip = $(this.options.template) 70 | } 71 | return this.$tip 72 | } 73 | 74 | }) 75 | 76 | 77 | /* POPOVER PLUGIN DEFINITION 78 | * ======================= */ 79 | 80 | $.fn.popover = function (option) { 81 | return this.each(function () { 82 | var $this = $(this) 83 | , data = $this.data('popover') 84 | , options = typeof option == 'object' && option 85 | if (!data) $this.data('popover', (data = new Popover(this, options))) 86 | if (typeof option == 'string') data[option]() 87 | }) 88 | } 89 | 90 | $.fn.popover.Constructor = Popover 91 | 92 | $.fn.popover.defaults = $.extend({} , $.fn.tooltip.defaults, { 93 | placement: 'right' 94 | , content: '' 95 | , template: '

' 96 | }) 97 | 98 | }(window.jQuery); -------------------------------------------------------------------------------- /js/bootstrap-tab.js: -------------------------------------------------------------------------------- 1 | /* ======================================================== 2 | * bootstrap-tab.js v2.0.3 3 | * http://twitter.github.com/bootstrap/javascript.html#tabs 4 | * ======================================================== 5 | * Copyright 2012 Twitter, Inc. 6 | * 7 | * Licensed under the Apache License, Version 2.0 (the "License"); 8 | * you may not use this file except in compliance with the License. 9 | * You may obtain a copy of the License at 10 | * 11 | * http://www.apache.org/licenses/LICENSE-2.0 12 | * 13 | * Unless required by applicable law or agreed to in writing, software 14 | * distributed under the License is distributed on an "AS IS" BASIS, 15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | * See the License for the specific language governing permissions and 17 | * limitations under the License. 18 | * ======================================================== */ 19 | 20 | 21 | !function ($) { 22 | 23 | "use strict"; // jshint ;_; 24 | 25 | 26 | /* TAB CLASS DEFINITION 27 | * ==================== */ 28 | 29 | var Tab = function ( element ) { 30 | this.element = $(element) 31 | } 32 | 33 | Tab.prototype = { 34 | 35 | constructor: Tab 36 | 37 | , show: function () { 38 | var $this = this.element 39 | , $ul = $this.closest('ul:not(.dropdown-menu)') 40 | , selector = $this.attr('data-target') 41 | , previous 42 | , $target 43 | , e 44 | 45 | if (!selector) { 46 | selector = $this.attr('href') 47 | selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7 48 | } 49 | 50 | if ( $this.parent('li').hasClass('active') ) return 51 | 52 | previous = $ul.find('.active a').last()[0] 53 | 54 | e = $.Event('show', { 55 | relatedTarget: previous 56 | }) 57 | 58 | $this.trigger(e) 59 | 60 | if (e.isDefaultPrevented()) return 61 | 62 | $target = $(selector) 63 | 64 | this.activate($this.parent('li'), $ul) 65 | this.activate($target, $target.parent(), function () { 66 | $this.trigger({ 67 | type: 'shown' 68 | , relatedTarget: previous 69 | }) 70 | }) 71 | } 72 | 73 | , activate: function ( element, container, callback) { 74 | var $active = container.find('> .active') 75 | , transition = callback 76 | && $.support.transition 77 | && $active.hasClass('fade') 78 | 79 | function next() { 80 | $active 81 | .removeClass('active') 82 | .find('> .dropdown-menu > .active') 83 | .removeClass('active') 84 | 85 | element.addClass('active') 86 | 87 | if (transition) { 88 | element[0].offsetWidth // reflow for transition 89 | element.addClass('in') 90 | } else { 91 | element.removeClass('fade') 92 | } 93 | 94 | if ( element.parent('.dropdown-menu') ) { 95 | element.closest('li.dropdown').addClass('active') 96 | } 97 | 98 | callback && callback() 99 | } 100 | 101 | transition ? 102 | $active.one($.support.transition.end, next) : 103 | next() 104 | 105 | $active.removeClass('in') 106 | } 107 | } 108 | 109 | 110 | /* TAB PLUGIN DEFINITION 111 | * ===================== */ 112 | 113 | $.fn.tab = function ( option ) { 114 | return this.each(function () { 115 | var $this = $(this) 116 | , data = $this.data('tab') 117 | if (!data) $this.data('tab', (data = new Tab(this))) 118 | if (typeof option == 'string') data[option]() 119 | }) 120 | } 121 | 122 | $.fn.tab.Constructor = Tab 123 | 124 | 125 | /* TAB DATA-API 126 | * ============ */ 127 | 128 | $(function () { 129 | $('body').on('click.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) { 130 | e.preventDefault() 131 | $(this).tab('show') 132 | }) 133 | }) 134 | 135 | }(window.jQuery); -------------------------------------------------------------------------------- /libraries/Zend/Cache/Backend/ExtendedInterface.php: -------------------------------------------------------------------------------- 1 | infinite lifetime) 68 | * @return boolean true if no problem 69 | */ 70 | public function save($data, $id, $tags = array(), $specificLifetime = false); 71 | 72 | /** 73 | * Remove a cache record 74 | * 75 | * @param string $id Cache id 76 | * @return boolean True if no problem 77 | */ 78 | public function remove($id); 79 | 80 | /** 81 | * Clean some cache records 82 | * 83 | * Available modes are : 84 | * Zend_Cache::CLEANING_MODE_ALL (default) => remove all cache entries ($tags is not used) 85 | * Zend_Cache::CLEANING_MODE_OLD => remove too old cache entries ($tags is not used) 86 | * Zend_Cache::CLEANING_MODE_MATCHING_TAG => remove cache entries matching all given tags 87 | * ($tags can be an array of strings or a single string) 88 | * Zend_Cache::CLEANING_MODE_NOT_MATCHING_TAG => remove cache entries not {matching one of the given tags} 89 | * ($tags can be an array of strings or a single string) 90 | * Zend_Cache::CLEANING_MODE_MATCHING_ANY_TAG => remove cache entries matching any given tags 91 | * ($tags can be an array of strings or a single string) 92 | * 93 | * @param string $mode Clean mode 94 | * @param array $tags Array of tags 95 | * @return boolean true if no problem 96 | */ 97 | public function clean($mode = Zend_Cache::CLEANING_MODE_ALL, $tags = array()); 98 | 99 | } 100 | -------------------------------------------------------------------------------- /libraries/Zend/Cache/Backend/ZendServer/Disk.php: -------------------------------------------------------------------------------- 1 | _options['namespace'] . '::' . $id, 64 | $data, 65 | $timeToLive) === false) { 66 | $this->_log('Store operation failed.'); 67 | return false; 68 | } 69 | return true; 70 | } 71 | 72 | /** 73 | * Fetch data 74 | * 75 | * @param string $id Cache id 76 | */ 77 | protected function _fetch($id) 78 | { 79 | return zend_disk_cache_fetch($this->_options['namespace'] . '::' . $id); 80 | } 81 | 82 | /** 83 | * Unset data 84 | * 85 | * @param string $id Cache id 86 | * @return boolean true if no problem 87 | */ 88 | protected function _unset($id) 89 | { 90 | return zend_disk_cache_delete($this->_options['namespace'] . '::' . $id); 91 | } 92 | 93 | /** 94 | * Clear cache 95 | */ 96 | protected function _clear() 97 | { 98 | zend_disk_cache_clear($this->_options['namespace']); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /libraries/Zend/Cache/Backend/ZendServer/ShMem.php: -------------------------------------------------------------------------------- 1 | _options['namespace'] . '::' . $id, 64 | $data, 65 | $timeToLive) === false) { 66 | $this->_log('Store operation failed.'); 67 | return false; 68 | } 69 | return true; 70 | } 71 | 72 | /** 73 | * Fetch data 74 | * 75 | * @param string $id Cache id 76 | */ 77 | protected function _fetch($id) 78 | { 79 | return zend_shm_cache_fetch($this->_options['namespace'] . '::' . $id); 80 | } 81 | 82 | /** 83 | * Unset data 84 | * 85 | * @param string $id Cache id 86 | * @return boolean true if no problem 87 | */ 88 | protected function _unset($id) 89 | { 90 | return zend_shm_cache_delete($this->_options['namespace'] . '::' . $id); 91 | } 92 | 93 | /** 94 | * Clear cache 95 | */ 96 | protected function _clear() 97 | { 98 | zend_shm_cache_clear($this->_options['namespace']); 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /libraries/Zend/Cache/Exception.php: -------------------------------------------------------------------------------- 1 | _tags = $tags; 60 | $this->_extension = $extension; 61 | ob_start(array($this, '_flush')); 62 | ob_implicit_flush(false); 63 | $this->_idStack[] = $id; 64 | return false; 65 | } 66 | 67 | /** 68 | * callback for output buffering 69 | * (shouldn't really be called manually) 70 | * 71 | * @param string $data Buffered output 72 | * @return string Data to send to browser 73 | */ 74 | public function _flush($data) 75 | { 76 | $id = array_pop($this->_idStack); 77 | if (is_null($id)) { 78 | Zend_Cache::throwException('use of _flush() without a start()'); 79 | } 80 | if ($this->_extension) { 81 | $this->save(serialize(array($data, $this->_extension)), $id, $this->_tags); 82 | } else { 83 | $this->save($data, $id, $this->_tags); 84 | } 85 | return $data; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /libraries/Zend/Cache/Frontend/Output.php: -------------------------------------------------------------------------------- 1 | _idStack = array(); 51 | } 52 | 53 | /** 54 | * Start the cache 55 | * 56 | * @param string $id Cache id 57 | * @param boolean $doNotTestCacheValidity If set to true, the cache validity won't be tested 58 | * @param boolean $echoData If set to true, datas are sent to the browser if the cache is hit (simpy returned else) 59 | * @return mixed True if the cache is hit (false else) with $echoData=true (default) ; string else (datas) 60 | */ 61 | public function start($id, $doNotTestCacheValidity = false, $echoData = true) 62 | { 63 | $data = $this->load($id, $doNotTestCacheValidity); 64 | if ($data !== false) { 65 | if ( $echoData ) { 66 | echo($data); 67 | return true; 68 | } else { 69 | return $data; 70 | } 71 | } 72 | ob_start(); 73 | ob_implicit_flush(false); 74 | $this->_idStack[] = $id; 75 | return false; 76 | } 77 | 78 | /** 79 | * Stop the cache 80 | * 81 | * @param array $tags Tags array 82 | * @param int $specificLifetime If != false, set a specific lifetime for this cache record (null => infinite lifetime) 83 | * @param string $forcedDatas If not null, force written datas with this 84 | * @param boolean $echoData If set to true, datas are sent to the browser 85 | * @param int $priority integer between 0 (very low priority) and 10 (maximum priority) used by some particular backends 86 | * @return void 87 | */ 88 | public function end($tags = array(), $specificLifetime = false, $forcedDatas = null, $echoData = true, $priority = 8) 89 | { 90 | if ($forcedDatas === null) { 91 | $data = ob_get_contents(); 92 | ob_end_clean(); 93 | } else { 94 | $data =& $forcedDatas; 95 | } 96 | $id = array_pop($this->_idStack); 97 | if ($id === null) { 98 | Zend_Cache::throwException('use of end() without a start()'); 99 | } 100 | $this->save($data, $id, $tags, $specificLifetime, $priority); 101 | if ($echoData) { 102 | echo($data); 103 | } 104 | } 105 | 106 | } 107 | -------------------------------------------------------------------------------- /libraries/Zend/Exception.php: -------------------------------------------------------------------------------- 1 | _previous = $previous; 47 | } else { 48 | parent::__construct($msg, (int) $code, $previous); 49 | } 50 | } 51 | 52 | /** 53 | * Overloading 54 | * 55 | * For PHP < 5.3.0, provides access to the getPrevious() method. 56 | * 57 | * @param string $method 58 | * @param array $args 59 | * @return mixed 60 | */ 61 | public function __call($method, array $args) 62 | { 63 | if ('getprevious' == strtolower($method)) { 64 | return $this->_getPrevious(); 65 | } 66 | return null; 67 | } 68 | 69 | /** 70 | * String representation of the exception 71 | * 72 | * @return string 73 | */ 74 | public function __toString() 75 | { 76 | if (version_compare(PHP_VERSION, '5.3.0', '<')) { 77 | if (null !== ($e = $this->getPrevious())) { 78 | return $e->__toString() 79 | . "\n\nNext " 80 | . parent::__toString(); 81 | } 82 | } 83 | return parent::__toString(); 84 | } 85 | 86 | /** 87 | * Returns previous Exception 88 | * 89 | * @return Exception|null 90 | */ 91 | protected function _getPrevious() 92 | { 93 | return $this->_previous; 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /libraries/feedwriter/FeedItem.php: -------------------------------------------------------------------------------- 1 | 9 | * @link http://www.ajaxray.com/projects/rss 10 | */ 11 | class FeedItem 12 | { 13 | private $elements = array(); //Collection of feed elements 14 | private $version; 15 | 16 | /** 17 | * Constructor 18 | * 19 | * @param contant (RSS1/RSS2/ATOM) RSS2 is default. 20 | */ 21 | function __construct($version = RSS2) 22 | { 23 | $this->version = $version; 24 | } 25 | 26 | /** 27 | * Add an element to elements array 28 | * 29 | * @access public 30 | * @param srting The tag name of an element 31 | * @param srting The content of tag 32 | * @param array Attributes(if any) in 'attrName' => 'attrValue' format 33 | * @return void 34 | */ 35 | public function addElement($elementName, $content, $attributes = null) 36 | { 37 | $this->elements[$elementName]['name'] = $elementName; 38 | $this->elements[$elementName]['content'] = $content; 39 | $this->elements[$elementName]['attributes'] = $attributes; 40 | } 41 | 42 | /** 43 | * Set multiple feed elements from an array. 44 | * Elements which have attributes cannot be added by this method 45 | * 46 | * @access public 47 | * @param array array of elements in 'tagName' => 'tagContent' format. 48 | * @return void 49 | */ 50 | public function addElementArray($elementArray) 51 | { 52 | if(! is_array($elementArray)) return; 53 | foreach ($elementArray as $elementName => $content) 54 | { 55 | $this->addElement($elementName, $content); 56 | } 57 | } 58 | 59 | /** 60 | * Return the collection of elements in this feed item 61 | * 62 | * @access public 63 | * @return array 64 | */ 65 | public function getElements() 66 | { 67 | return $this->elements; 68 | } 69 | 70 | // Wrapper functions ------------------------------------------------------ 71 | 72 | /** 73 | * Set the 'dscription' element of feed item 74 | * 75 | * @access public 76 | * @param string The content of 'description' element 77 | * @return void 78 | */ 79 | public function setDescription($description) 80 | { 81 | $tag = ($this->version == ATOM)? 'summary' : 'description'; 82 | $this->addElement($tag, $description); 83 | } 84 | 85 | /** 86 | * @desc Set the 'title' element of feed item 87 | * @access public 88 | * @param string The content of 'title' element 89 | * @return void 90 | */ 91 | public function setTitle($title) 92 | { 93 | $this->addElement('title', $title); 94 | } 95 | 96 | /** 97 | * Set the 'date' element of feed item 98 | * 99 | * @access public 100 | * @param string The content of 'date' element 101 | * @return void 102 | */ 103 | public function setDate($date) 104 | { 105 | if(! is_numeric($date)) 106 | { 107 | $date = strtotime($date); 108 | } 109 | 110 | if($this->version == ATOM) 111 | { 112 | $tag = 'updated'; 113 | $value = date(DATE_ATOM, $date); 114 | } 115 | elseif($this->version == RSS2) 116 | { 117 | $tag = 'pubDate'; 118 | $value = date(DATE_RSS, $date); 119 | } 120 | else 121 | { 122 | $tag = 'dc:date'; 123 | $value = date("Y-m-d", $date); 124 | } 125 | 126 | $this->addElement($tag, $value); 127 | } 128 | 129 | /** 130 | * Set the 'link' element of feed item 131 | * 132 | * @access public 133 | * @param string The content of 'link' element 134 | * @return void 135 | */ 136 | public function setLink($link) 137 | { 138 | if($this->version == RSS2 || $this->version == RSS1) 139 | { 140 | $this->addElement('link', $link); 141 | } 142 | else 143 | { 144 | $this->addElement('link','',array('href'=>$link)); 145 | $this->addElement('id', FeedWriter::uuid($link,'urn:uuid:')); 146 | } 147 | 148 | } 149 | 150 | /** 151 | * Set the 'encloser' element of feed item 152 | * For RSS 2.0 only 153 | * 154 | * @access public 155 | * @param string The url attribute of encloser tag 156 | * @param string The length attribute of encloser tag 157 | * @param string The type attribute of encloser tag 158 | * @return void 159 | */ 160 | public function setEncloser($url, $length, $type) 161 | { 162 | $attributes = array('url'=>$url, 'length'=>$length, 'type'=>$type); 163 | $this->addElement('enclosure','',$attributes); 164 | } 165 | 166 | } // end of class FeedItem 167 | ?> 168 | -------------------------------------------------------------------------------- /libraries/humble-http-agent/SimplePie_HumbleHttpAgent.php: -------------------------------------------------------------------------------- 1 | encode($parsed['authority']), $parsed['path'], $parsed['query'], $parsed['fragment']); 37 | } 38 | $this->url = $url; 39 | $this->useragent = $useragent; 40 | if (preg_match('/^http(s)?:\/\//i', $url)) 41 | { 42 | if (!is_array($headers)) 43 | { 44 | $headers = array(); 45 | } 46 | $this->method = SIMPLEPIE_FILE_SOURCE_REMOTE | SIMPLEPIE_FILE_SOURCE_CURL; 47 | $headers2 = array(); 48 | foreach ($headers as $key => $value) { 49 | $headers2[] = "$key: $value"; 50 | } 51 | //TODO: allow for HTTP headers 52 | // curl_setopt($fp, CURLOPT_HTTPHEADER, $headers2); 53 | 54 | $response = self::$agent->get($url); 55 | 56 | if ($response === false || !isset($response['status_code'])) { 57 | $this->error = 'failed to fetch URL'; 58 | $this->success = false; 59 | } else { 60 | // The extra lines at the end are there to satisfy SimplePie's HTTP parser. 61 | // The class expects a full HTTP message, whereas we're giving it only 62 | // headers - the new lines indicate the start of the body. 63 | $parser = new SimplePie_HTTP_Parser($response['headers']."\r\n\r\n"); 64 | if ($parser->parse()) { 65 | $this->headers = $parser->headers; 66 | //$this->body = $parser->body; 67 | $this->body = $response['body']; 68 | $this->status_code = $parser->status_code; 69 | } 70 | } 71 | } 72 | else 73 | { 74 | $this->error = 'invalid URL'; 75 | $this->success = false; 76 | } 77 | } 78 | } 79 | ?> -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/LICENSE.BSD: -------------------------------------------------------------------------------- 1 | Redistribution and use in source and binary forms, with or without 2 | modification, are permitted provided that the following conditions are met: 3 | 4 | * Redistributions of source code must retain the above copyright 5 | notice, this list of conditions and the following disclaimer. 6 | * Redistributions in binary form must reproduce the above copyright 7 | notice, this list of conditions and the following disclaimer in the 8 | documentation and/or other materials provided with the distribution. 9 | * Neither the name of the nor the 10 | names of its contributors may be used to endorse or promote products 11 | derived from this software without specific prior written permission. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 14 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 16 | ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY 17 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 22 | THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/README.md: -------------------------------------------------------------------------------- 1 | # [PhantomJS](http://phantomjs.org) - Scriptable Headless WebKit 2 | 3 | PhantomJS ([phantomjs.org](http://phantomjs.org)) is a headless WebKit scriptable with JavaScript. The latest [stable release](http://phantomjs.org/release-2.0.html) is version 2.0. 4 | 5 | **Note**: Please **do not** create a GitHub pull request **without** reading the [Contribution Guide](https://github.com/ariya/phantomjs/blob/master/CONTRIBUTING.md) first. Failure to do so may result in the rejection of the pull request. 6 | 7 | ## Use Cases 8 | 9 | - **Headless web testing**. Lightning-fast testing without the browser is now possible! 10 | - **Page automation**. [Access and manipulate](http://phantomjs.org/page-automation.html) web pages with the standard DOM API, or with usual libraries like jQuery. 11 | - **Screen capture**. Programmatically [capture web contents](http://phantomjs.org/screen-capture.html), including CSS, SVG and Canvas. Build server-side web graphics apps, from a screenshot service to a vector chart rasterizer. 12 | - **Network monitoring**. Automate performance analysis, track [page loading](http://phantomjs.org/network-monitoring.html) and export as standard HAR format. 13 | 14 | ## Features 15 | 16 | - **Multiplatform**, available on major operating systems: Windows, Mac OS X, Linux, and other Unices. 17 | - **Fast and native implementation** of web standards: DOM, CSS, JavaScript, Canvas, and SVG. No emulation! 18 | - **Pure headless (no X11) on Linux**, ideal for continuous integration systems. Also runs on Amazon EC2, Heroku, and Iron.io. 19 | - **Easy to install**: [Download](http://phantomjs.org/download.html), unpack, and start having fun in just 5 minutes. 20 | 21 | ## Questions? 22 | 23 | - Explore the complete [documentation](http://phantomjs.org/documentation/). 24 | - Read tons of [user articles](http://phantomjs.org/buzz.html) on using PhantomJS. 25 | - Join the [mailing-list](http://groups.google.com/group/phantomjs) and discuss with other PhantomJS fans. 26 | 27 | PhantomJS is free software/open source, and is distributed under the [BSD license](http://opensource.org/licenses/BSD-3-Clause). It contains third-party code, see the included `third-party.txt` file for the license information on third-party code. 28 | 29 | PhantomJS is created and maintained by [Ariya Hidayat](http://ariya.ofilabs.com/about) (Twitter: [@ariyahidayat](http://twitter.com/ariyahidayat)), with the help of [many contributors](https://github.com/ariya/phantomjs/contributors). Follow the official Twitter stream [@PhantomJS](http://twitter.com/PhantomJS) to get the frequent development updates. 30 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/bin/phantomjs-exec.js: -------------------------------------------------------------------------------- 1 | // ./phantomjs phantomjs-exec.js "https://gnn.gamer.com.tw/3/144513.html" "div.GN-lbox3B" 2 | 3 | var config = {}; 4 | config.enable_cache = true; 5 | config.cache_dir = "/tmp/phantomjs_cache/"; 6 | config.output = "/tmp/phantomjs_cache/phantomjs_output.html"; 7 | //console.log("00000"); 8 | //phantom.exit(); 9 | // -------------------------------- 10 | 11 | var webpage = require('webpage').create(); 12 | var webpage2 = require('webpage').create(); 13 | var execFile = require('child_process').execFile; 14 | var fs = require('fs'); 15 | system = require('system'); 16 | 17 | config.url; // = 'https://gnn.gamer.com.tw/3/144513.html'; 18 | //global selector; 19 | 20 | // -------------------------------- 21 | 22 | var _get_url = function (_callback) { 23 | if (typeof(system.args[1]) === 'string') { 24 | config.url = system.args[1]; 25 | } 26 | else { 27 | phantom.exit(); 28 | } 29 | 30 | if (typeof(system.args[2]) === 'string') { 31 | config.selector = system.args[2]; 32 | } 33 | 34 | //JSON.toString(system.args); 35 | //phantom.exit(); 36 | }; 37 | 38 | // -------------------------------- 39 | 40 | var _mkdir_cache = function (config, _callback) { 41 | /* 42 | if (config.enable_cache === false) { 43 | return _callback(); 44 | } 45 | */ 46 | 47 | if(fs.isDirectory(config.cache_dir) === false) { 48 | execFile("mkdir", ["-p", "/tmp/phantomjs_cache/"], null, function () { 49 | //console.log("ok1"); 50 | //phantom.exit(); 51 | execFile("chmod", ["777", "/tmp/phantomjs_cache/"], null, function () { 52 | _callback(); 53 | }); 54 | }); 55 | } 56 | else { 57 | //console.log("ok2"); 58 | //phantom.exit(); 59 | _callback(); 60 | } 61 | 62 | }; 63 | 64 | var _cache_filepath = function (config) { 65 | var _path = escape(config.url); 66 | _path = _path.replace(/\//g, '') 67 | return config.cache_dir + _path + ".html"; 68 | }; 69 | 70 | var _read_cache = function (config, _callback) { 71 | if (config.enable_cache === false) { 72 | return _callback(); 73 | } 74 | 75 | var _file = _cache_filepath(config); 76 | if (fs.exists(_file)) { 77 | content = fs.read(_file); 78 | console.log(content); 79 | fs.write(config.output, content, 'w'); 80 | phantom.exit(); 81 | } 82 | else { 83 | _callback(); 84 | } 85 | }; 86 | 87 | 88 | // ---------------------------- 89 | 90 | var _open_webpage = function (config, _callback) { 91 | 92 | var onPageReady = function() { 93 | if (config.selector !== undefined) { 94 | //console.log(1); 95 | var htmlContent = eval('webpage.evaluate(function () {' 96 | + ' htmlContent = $(document).find("' + config.selector + '").html();' 97 | + ' return htmlContent;' 98 | + '})'); 99 | //console.log(htmlContent); 100 | } 101 | else { 102 | var htmlContent = webpage.evaluate(function () { 103 | return document.documentElement.outerHTML; 104 | }); 105 | } 106 | _finish(config, htmlContent, _callback); 107 | }; 108 | 109 | console.log("Load: " + config.url); 110 | webpage.open(config.url, function() { 111 | webpage.injectJs('jquery.js'); 112 | function checkReadyState() { 113 | setTimeout(function () { 114 | //console.log("0"); 115 | var readyState = webpage.evaluate(function () { 116 | return document.readyState; 117 | }); 118 | 119 | if ("complete" === readyState) { 120 | onPageReady(); 121 | } else { 122 | checkReadyState(); 123 | } 124 | }, 500); 125 | } 126 | 127 | checkReadyState(); 128 | }); 129 | }; 130 | 131 | var _finish = function (config, htmlContent, _callback) { 132 | 133 | var content = htmlContent; 134 | console.log(content); 135 | 136 | //fs.remove(config.output); 137 | fs.write(config.output, content, 'w'); 138 | 139 | if (config.enable_cache === false) { 140 | return _callback(); 141 | } 142 | 143 | var path = _cache_filepath(config); 144 | //var content = ; 145 | fs.write(path, content, 'w'); 146 | 147 | return _callback(); 148 | }; 149 | 150 | // ---------------------------- 151 | 152 | _get_url(); 153 | //console.log("c"); 154 | _mkdir_cache(config, function () { 155 | //console.log("a"); 156 | _read_cache(config, function () { 157 | //console.log("b"); 158 | _open_webpage(config, function () { 159 | phantom.exit(); 160 | }); 161 | }); 162 | }); 163 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/bin/test.sh: -------------------------------------------------------------------------------- 1 | ./phantomjs phantomjs-exec.js https://gnn.gamer.com.tw/3/144513.html div.GN-lbox3B 2 | #./phantomjs phantomjs-exec.js http://feedproxy.google.com/~r/soft4funtw/~3/rac3ogF7aFU/facebook-will-expand-ad-slot-in-instant-articles.htm div.lucy-content 3 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/arguments.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | if (system.args.length === 1) { 4 | console.log('Try to pass some args when invoking this script!'); 5 | } else { 6 | system.args.forEach(function (arg, i) { 7 | console.log(i + ': ' + arg); 8 | }); 9 | } 10 | phantom.exit(); 11 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/child_process-examples.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var spawn = require("child_process").spawn 3 | var execFile = require("child_process").execFile 4 | 5 | var child = spawn("ls", ["-lF", "/rooot"]) 6 | 7 | child.stdout.on("data", function (data) { 8 | console.log("spawnSTDOUT:", JSON.stringify(data)) 9 | }) 10 | 11 | child.stderr.on("data", function (data) { 12 | console.log("spawnSTDERR:", JSON.stringify(data)) 13 | }) 14 | 15 | child.on("exit", function (code) { 16 | console.log("spawnEXIT:", code) 17 | }) 18 | 19 | //child.kill("SIGKILL") 20 | 21 | execFile("ls", ["-lF", "/usr"], null, function (err, stdout, stderr) { 22 | console.log("execFileSTDOUT:", JSON.stringify(stdout)) 23 | console.log("execFileSTDERR:", JSON.stringify(stderr)) 24 | }) 25 | 26 | setTimeout(function () { 27 | phantom.exit(0) 28 | }, 2000) 29 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/colorwheel.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(); 3 | page.viewportSize = { width: 400, height : 400 }; 4 | page.content = ''; 5 | page.evaluate(function() { 6 | var el = document.getElementById('surface'), 7 | context = el.getContext('2d'), 8 | width = window.innerWidth, 9 | height = window.innerHeight, 10 | cx = width / 2, 11 | cy = height / 2, 12 | radius = width / 2.3, 13 | imageData, 14 | pixels, 15 | hue, sat, value, 16 | i = 0, x, y, rx, ry, d, 17 | f, g, p, u, v, w, rgb; 18 | 19 | el.width = width; 20 | el.height = height; 21 | imageData = context.createImageData(width, height); 22 | pixels = imageData.data; 23 | 24 | for (y = 0; y < height; y = y + 1) { 25 | for (x = 0; x < width; x = x + 1, i = i + 4) { 26 | rx = x - cx; 27 | ry = y - cy; 28 | d = rx * rx + ry * ry; 29 | if (d < radius * radius) { 30 | hue = 6 * (Math.atan2(ry, rx) + Math.PI) / (2 * Math.PI); 31 | sat = Math.sqrt(d) / radius; 32 | g = Math.floor(hue); 33 | f = hue - g; 34 | u = 255 * (1 - sat); 35 | v = 255 * (1 - sat * f); 36 | w = 255 * (1 - sat * (1 - f)); 37 | pixels[i] = [255, v, u, u, w, 255, 255][g]; 38 | pixels[i + 1] = [w, 255, 255, v, u, u, w][g]; 39 | pixels[i + 2] = [u, u, w, 255, 255, v, u][g]; 40 | pixels[i + 3] = 255; 41 | } 42 | } 43 | } 44 | 45 | context.putImageData(imageData, 0, 0); 46 | document.body.style.backgroundColor = 'white'; 47 | document.body.style.margin = '0px'; 48 | }); 49 | 50 | page.render('colorwheel.png'); 51 | 52 | phantom.exit(); 53 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/countdown.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var t = 10, 3 | interval = setInterval(function(){ 4 | if ( t > 0 ) { 5 | console.log(t--); 6 | } else { 7 | console.log("BLAST OFF!"); 8 | phantom.exit(); 9 | } 10 | }, 1000); 11 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/detectsniff.js: -------------------------------------------------------------------------------- 1 | // Detect if a web page sniffs the user agent or not. 2 | 3 | "use strict"; 4 | var page = require('webpage').create(), 5 | system = require('system'), 6 | sniffed, 7 | address; 8 | 9 | page.onInitialized = function () { 10 | page.evaluate(function () { 11 | 12 | (function () { 13 | var userAgent = window.navigator.userAgent, 14 | platform = window.navigator.platform; 15 | 16 | window.navigator = { 17 | appCodeName: 'Mozilla', 18 | appName: 'Netscape', 19 | cookieEnabled: false, 20 | sniffed: false 21 | }; 22 | 23 | window.navigator.__defineGetter__('userAgent', function () { 24 | window.navigator.sniffed = true; 25 | return userAgent; 26 | }); 27 | 28 | window.navigator.__defineGetter__('platform', function () { 29 | window.navigator.sniffed = true; 30 | return platform; 31 | }); 32 | })(); 33 | }); 34 | }; 35 | 36 | if (system.args.length === 1) { 37 | console.log('Usage: detectsniff.js '); 38 | phantom.exit(1); 39 | } else { 40 | address = system.args[1]; 41 | console.log('Checking ' + address + '...'); 42 | page.open(address, function (status) { 43 | if (status !== 'success') { 44 | console.log('FAIL to load the address'); 45 | phantom.exit(); 46 | } else { 47 | window.setTimeout(function () { 48 | sniffed = page.evaluate(function () { 49 | return navigator.sniffed; 50 | }); 51 | if (sniffed) { 52 | console.log('The page tried to sniff the user agent.'); 53 | } else { 54 | console.log('The page did not try to sniff the user agent.'); 55 | } 56 | phantom.exit(); 57 | }, 1500); 58 | } 59 | }); 60 | } 61 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/echoToFile.js: -------------------------------------------------------------------------------- 1 | // echoToFile.js - Write in a given file all the parameters passed on the CLI 2 | "use strict"; 3 | var fs = require('fs'), 4 | system = require('system'); 5 | 6 | if (system.args.length < 3) { 7 | console.log("Usage: echoToFile.js DESTINATION_FILE "); 8 | phantom.exit(1); 9 | } else { 10 | var content = '', 11 | f = null, 12 | i; 13 | for ( i= 2; i < system.args.length; ++i ) { 14 | content += system.args[i] + (i === system.args.length-1 ? '' : ' '); 15 | } 16 | 17 | try { 18 | fs.write(system.args[1], content, 'w'); 19 | } catch(e) { 20 | console.log(e); 21 | } 22 | 23 | phantom.exit(); 24 | } 25 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/features.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var feature, supported = [], unsupported = []; 3 | 4 | phantom.injectJs('modernizr.js'); 5 | console.log('Detected features (using Modernizr ' + Modernizr._version + '):'); 6 | for (feature in Modernizr) { 7 | if (Modernizr.hasOwnProperty(feature)) { 8 | if (feature[0] !== '_' && typeof Modernizr[feature] !== 'function' && 9 | feature !== 'input' && feature !== 'inputtypes') { 10 | if (Modernizr[feature]) { 11 | supported.push(feature); 12 | } else { 13 | unsupported.push(feature); 14 | } 15 | } 16 | } 17 | } 18 | 19 | console.log(''); 20 | console.log('Supported:'); 21 | supported.forEach(function (e) { 22 | console.log(' ' + e); 23 | }); 24 | 25 | console.log(''); 26 | console.log('Not supported:'); 27 | unsupported.forEach(function (e) { 28 | console.log(' ' + e); 29 | }); 30 | phantom.exit(); 31 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/fibo.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var fibs = [0, 1]; 3 | var ticker = window.setInterval(function () { 4 | console.log(fibs[fibs.length - 1]); 5 | fibs.push(fibs[fibs.length - 1] + fibs[fibs.length - 2]); 6 | if (fibs.length > 10) { 7 | window.clearInterval(ticker); 8 | phantom.exit(); 9 | } 10 | }, 300); 11 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/hello.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | console.log('Hello, world!'); 3 | phantom.exit(); 4 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/injectme.js: -------------------------------------------------------------------------------- 1 | // Use 'page.injectJs()' to load the script itself in the Page context 2 | 3 | "use strict"; 4 | if ( typeof(phantom) !== "undefined" ) { 5 | var page = require('webpage').create(); 6 | 7 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 8 | page.onConsoleMessage = function(msg) { 9 | console.log(msg); 10 | }; 11 | 12 | page.onAlert = function(msg) { 13 | console.log(msg); 14 | }; 15 | 16 | console.log("* Script running in the Phantom context."); 17 | console.log("* Script will 'inject' itself in a page..."); 18 | page.open("about:blank", function(status) { 19 | if ( status === "success" ) { 20 | console.log(page.injectJs("injectme.js") ? "... done injecting itself!" : "... fail! Check the $PWD?!"); 21 | } 22 | phantom.exit(); 23 | }); 24 | } else { 25 | alert("* Script running in the Page context."); 26 | } 27 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/loadspeed.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'), 4 | t, address; 5 | 6 | if (system.args.length === 1) { 7 | console.log('Usage: loadspeed.js '); 8 | phantom.exit(1); 9 | } else { 10 | t = Date.now(); 11 | address = system.args[1]; 12 | page.open(address, function (status) { 13 | if (status !== 'success') { 14 | console.log('FAIL to load the address'); 15 | } else { 16 | t = Date.now() - t; 17 | console.log('Page title is ' + page.evaluate(function () { 18 | return document.title; 19 | })); 20 | console.log('Loading time ' + t + ' msec'); 21 | } 22 | phantom.exit(); 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/loadurlwithoutcss.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'); 4 | 5 | if (system.args.length < 2) { 6 | console.log('Usage: loadurlwithoutcss.js URL'); 7 | phantom.exit(); 8 | } 9 | 10 | var address = system.args[1]; 11 | 12 | page.onResourceRequested = function(requestData, request) { 13 | if ((/http:\/\/.+?\.css/gi).test(requestData['url']) || requestData.headers['Content-Type'] == 'text/css') { 14 | console.log('The url of the request is matching. Aborting: ' + requestData['url']); 15 | request.abort(); 16 | } 17 | }; 18 | 19 | page.open(address, function(status) { 20 | if (status === 'success') { 21 | phantom.exit(); 22 | } else { 23 | console.log('Unable to load the address!'); 24 | phantom.exit(); 25 | } 26 | }); -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/module.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var universe = require('./universe'); 3 | universe.start(); 4 | console.log('The answer is ' + universe.answer); 5 | phantom.exit(); 6 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/netlog.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'), 4 | address; 5 | 6 | if (system.args.length === 1) { 7 | console.log('Usage: netlog.js '); 8 | phantom.exit(1); 9 | } else { 10 | address = system.args[1]; 11 | 12 | page.onResourceRequested = function (req) { 13 | console.log('requested: ' + JSON.stringify(req, undefined, 4)); 14 | }; 15 | 16 | page.onResourceReceived = function (res) { 17 | console.log('received: ' + JSON.stringify(res, undefined, 4)); 18 | }; 19 | 20 | page.open(address, function (status) { 21 | if (status !== 'success') { 22 | console.log('FAIL to load the address'); 23 | } 24 | phantom.exit(); 25 | }); 26 | } 27 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/netsniff.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | if (!Date.prototype.toISOString) { 3 | Date.prototype.toISOString = function () { 4 | function pad(n) { return n < 10 ? '0' + n : n; } 5 | function ms(n) { return n < 10 ? '00'+ n : n < 100 ? '0' + n : n } 6 | return this.getFullYear() + '-' + 7 | pad(this.getMonth() + 1) + '-' + 8 | pad(this.getDate()) + 'T' + 9 | pad(this.getHours()) + ':' + 10 | pad(this.getMinutes()) + ':' + 11 | pad(this.getSeconds()) + '.' + 12 | ms(this.getMilliseconds()) + 'Z'; 13 | } 14 | } 15 | 16 | function createHAR(address, title, startTime, resources) 17 | { 18 | var entries = []; 19 | 20 | resources.forEach(function (resource) { 21 | var request = resource.request, 22 | startReply = resource.startReply, 23 | endReply = resource.endReply; 24 | 25 | if (!request || !startReply || !endReply) { 26 | return; 27 | } 28 | 29 | // Exclude Data URI from HAR file because 30 | // they aren't included in specification 31 | if (request.url.match(/(^data:image\/.*)/i)) { 32 | return; 33 | } 34 | 35 | entries.push({ 36 | startedDateTime: request.time.toISOString(), 37 | time: endReply.time - request.time, 38 | request: { 39 | method: request.method, 40 | url: request.url, 41 | httpVersion: "HTTP/1.1", 42 | cookies: [], 43 | headers: request.headers, 44 | queryString: [], 45 | headersSize: -1, 46 | bodySize: -1 47 | }, 48 | response: { 49 | status: endReply.status, 50 | statusText: endReply.statusText, 51 | httpVersion: "HTTP/1.1", 52 | cookies: [], 53 | headers: endReply.headers, 54 | redirectURL: "", 55 | headersSize: -1, 56 | bodySize: startReply.bodySize, 57 | content: { 58 | size: startReply.bodySize, 59 | mimeType: endReply.contentType 60 | } 61 | }, 62 | cache: {}, 63 | timings: { 64 | blocked: 0, 65 | dns: -1, 66 | connect: -1, 67 | send: 0, 68 | wait: startReply.time - request.time, 69 | receive: endReply.time - startReply.time, 70 | ssl: -1 71 | }, 72 | pageref: address 73 | }); 74 | }); 75 | 76 | return { 77 | log: { 78 | version: '1.2', 79 | creator: { 80 | name: "PhantomJS", 81 | version: phantom.version.major + '.' + phantom.version.minor + 82 | '.' + phantom.version.patch 83 | }, 84 | pages: [{ 85 | startedDateTime: startTime.toISOString(), 86 | id: address, 87 | title: title, 88 | pageTimings: { 89 | onLoad: page.endTime - page.startTime 90 | } 91 | }], 92 | entries: entries 93 | } 94 | }; 95 | } 96 | 97 | var page = require('webpage').create(), 98 | system = require('system'); 99 | 100 | if (system.args.length === 1) { 101 | console.log('Usage: netsniff.js '); 102 | phantom.exit(1); 103 | } else { 104 | 105 | page.address = system.args[1]; 106 | page.resources = []; 107 | 108 | page.onLoadStarted = function () { 109 | page.startTime = new Date(); 110 | }; 111 | 112 | page.onResourceRequested = function (req) { 113 | page.resources[req.id] = { 114 | request: req, 115 | startReply: null, 116 | endReply: null 117 | }; 118 | }; 119 | 120 | page.onResourceReceived = function (res) { 121 | if (res.stage === 'start') { 122 | page.resources[res.id].startReply = res; 123 | } 124 | if (res.stage === 'end') { 125 | page.resources[res.id].endReply = res; 126 | } 127 | }; 128 | 129 | page.open(page.address, function (status) { 130 | var har; 131 | if (status !== 'success') { 132 | console.log('FAIL to load the address'); 133 | phantom.exit(1); 134 | } else { 135 | page.endTime = new Date(); 136 | page.title = page.evaluate(function () { 137 | return document.title; 138 | }); 139 | har = createHAR(page.address, page.title, page.startTime, page.resources); 140 | console.log(JSON.stringify(har, undefined, 4)); 141 | phantom.exit(); 142 | } 143 | }); 144 | } 145 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/openurlwithproxy.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'), 4 | host, port, address; 5 | 6 | if (system.args.length < 4) { 7 | console.log('Usage: openurlwithproxy.js '); 8 | phantom.exit(1); 9 | } else { 10 | host = system.args[1]; 11 | port = system.args[2]; 12 | address = system.args[3]; 13 | phantom.setProxy(host, port, 'manual', '', ''); 14 | page.open(address, function (status) { 15 | if (status !== 'success') { 16 | console.log('FAIL to load the address "' + 17 | address + '" using proxy "' + host + ':' + port + '"'); 18 | } else { 19 | console.log('Page title is ' + page.evaluate(function () { 20 | return document.title; 21 | })); 22 | } 23 | phantom.exit(); 24 | }); 25 | } 26 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/outputEncoding.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function helloWorld() { 3 | console.log(phantom.outputEncoding + ": こんにちは、世界!"); 4 | } 5 | 6 | console.log("Using default encoding..."); 7 | helloWorld(); 8 | 9 | console.log("\nUsing other encodings..."); 10 | 11 | var encodings = ["euc-jp", "sjis", "utf8", "System"]; 12 | for (var i = 0; i < encodings.length; i++) { 13 | phantom.outputEncoding = encodings[i]; 14 | helloWorld(); 15 | } 16 | 17 | phantom.exit() 18 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/pagecallback.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var p = require("webpage").create(); 3 | 4 | p.onConsoleMessage = function(msg) { console.log(msg); }; 5 | 6 | // Calls to "callPhantom" within the page 'p' arrive here 7 | p.onCallback = function(msg) { 8 | console.log("Received by the 'phantom' main context: "+msg); 9 | return "Hello there, I'm coming to you from the 'phantom' context instead"; 10 | }; 11 | 12 | p.evaluate(function() { 13 | // Return-value of the "onCallback" handler arrive here 14 | var callbackResponse = window.callPhantom("Hello, I'm coming to you from the 'page' context"); 15 | console.log("Received by the 'page' context: "+callbackResponse); 16 | }); 17 | 18 | phantom.exit(); 19 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/phantomwebintro.js: -------------------------------------------------------------------------------- 1 | // Read the Phantom webpage '#intro' element text using jQuery and "includeJs" 2 | 3 | "use strict"; 4 | var page = require('webpage').create(); 5 | 6 | page.onConsoleMessage = function(msg) { 7 | console.log(msg); 8 | }; 9 | 10 | page.open("http://phantomjs.org/", function(status) { 11 | if (status === "success") { 12 | page.includeJs("http://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js", function() { 13 | page.evaluate(function() { 14 | console.log("$(\".explanation\").text() -> " + $(".explanation").text()); 15 | }); 16 | phantom.exit(0); 17 | }); 18 | } else { 19 | phantom.exit(1); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/post.js: -------------------------------------------------------------------------------- 1 | // Example using HTTP POST operation 2 | 3 | "use strict"; 4 | var page = require('webpage').create(), 5 | server = 'http://posttestserver.com/post.php?dump', 6 | data = 'universe=expanding&answer=42'; 7 | 8 | page.open(server, 'post', data, function (status) { 9 | if (status !== 'success') { 10 | console.log('Unable to post!'); 11 | } else { 12 | console.log(page.content); 13 | } 14 | phantom.exit(); 15 | }); 16 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/postjson.js: -------------------------------------------------------------------------------- 1 | // Example using HTTP POST operation 2 | 3 | "use strict"; 4 | var page = require('webpage').create(), 5 | server = 'http://posttestserver.com/post.php?dump', 6 | data = '{"universe": "expanding", "answer": 42}'; 7 | 8 | var headers = { 9 | "Content-Type": "application/json" 10 | } 11 | 12 | page.open(server, 'post', data, headers, function (status) { 13 | if (status !== 'success') { 14 | console.log('Unable to post!'); 15 | } else { 16 | console.log(page.content); 17 | } 18 | phantom.exit(); 19 | }); 20 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/postserver.js: -------------------------------------------------------------------------------- 1 | // Example using HTTP POST operation 2 | 3 | "use strict"; 4 | var page = require('webpage').create(), 5 | server = require('webserver').create(), 6 | system = require('system'), 7 | data = 'universe=expanding&answer=42'; 8 | 9 | if (system.args.length !== 2) { 10 | console.log('Usage: postserver.js '); 11 | phantom.exit(1); 12 | } 13 | 14 | var port = system.args[1]; 15 | 16 | service = server.listen(port, function (request, response) { 17 | console.log('Request received at ' + new Date()); 18 | 19 | response.statusCode = 200; 20 | response.headers = { 21 | 'Cache': 'no-cache', 22 | 'Content-Type': 'text/plain;charset=utf-8' 23 | }; 24 | response.write(JSON.stringify(request, null, 4)); 25 | response.close(); 26 | }); 27 | 28 | page.open('http://localhost:' + port + '/', 'post', data, function (status) { 29 | if (status !== 'success') { 30 | console.log('Unable to post!'); 31 | } else { 32 | console.log(page.plainText); 33 | } 34 | phantom.exit(); 35 | }); 36 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/printenv.js: -------------------------------------------------------------------------------- 1 | var system = require('system'), 2 | env = system.env, 3 | key; 4 | 5 | for (key in env) { 6 | if (env.hasOwnProperty(key)) { 7 | console.log(key + '=' + env[key]); 8 | } 9 | } 10 | phantom.exit(); 11 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/printheaderfooter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'); 4 | 5 | function someCallback(pageNum, numPages) { 6 | return "

someCallback: " + pageNum + " / " + numPages + "

"; 7 | } 8 | 9 | if (system.args.length < 3) { 10 | console.log('Usage: printheaderfooter.js URL filename'); 11 | phantom.exit(1); 12 | } else { 13 | var address = system.args[1]; 14 | var output = system.args[2]; 15 | page.viewportSize = { width: 600, height: 600 }; 16 | page.paperSize = { 17 | format: 'A4', 18 | margin: "1cm", 19 | /* default header/footer for pages that don't have custom overwrites (see below) */ 20 | header: { 21 | height: "1cm", 22 | contents: phantom.callback(function(pageNum, numPages) { 23 | if (pageNum == 1) { 24 | return ""; 25 | } 26 | return "

Header " + pageNum + " / " + numPages + "

"; 27 | }) 28 | }, 29 | footer: { 30 | height: "1cm", 31 | contents: phantom.callback(function(pageNum, numPages) { 32 | if (pageNum == numPages) { 33 | return ""; 34 | } 35 | return "

Footer " + pageNum + " / " + numPages + "

"; 36 | }) 37 | } 38 | }; 39 | page.open(address, function (status) { 40 | if (status !== 'success') { 41 | console.log('Unable to load the address!'); 42 | } else { 43 | /* check whether the loaded page overwrites the header/footer setting, 44 | i.e. whether a PhantomJSPriting object exists. Use that then instead 45 | of our defaults above. 46 | 47 | example: 48 | 49 | 50 | 62 | 63 |

asdfadsf

asdfadsfycvx

64 | 65 | */ 66 | if (page.evaluate(function(){return typeof PhantomJSPrinting == "object";})) { 67 | paperSize = page.paperSize; 68 | paperSize.header.height = page.evaluate(function() { 69 | return PhantomJSPrinting.header.height; 70 | }); 71 | paperSize.header.contents = phantom.callback(function(pageNum, numPages) { 72 | return page.evaluate(function(pageNum, numPages){return PhantomJSPrinting.header.contents(pageNum, numPages);}, pageNum, numPages); 73 | }); 74 | paperSize.footer.height = page.evaluate(function() { 75 | return PhantomJSPrinting.footer.height; 76 | }); 77 | paperSize.footer.contents = phantom.callback(function(pageNum, numPages) { 78 | return page.evaluate(function(pageNum, numPages){return PhantomJSPrinting.footer.contents(pageNum, numPages);}, pageNum, numPages); 79 | }); 80 | page.paperSize = paperSize; 81 | console.log(page.paperSize.header.height); 82 | console.log(page.paperSize.footer.height); 83 | } 84 | window.setTimeout(function () { 85 | page.render(output); 86 | phantom.exit(); 87 | }, 200); 88 | } 89 | }); 90 | } 91 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/printmargins.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'); 4 | 5 | if (system.args.length < 7) { 6 | console.log('Usage: printmargins.js URL filename LEFT TOP RIGHT BOTTOM'); 7 | console.log(' margin examples: "1cm", "10px", "7mm", "5in"'); 8 | phantom.exit(1); 9 | } else { 10 | var address = system.args[1]; 11 | var output = system.args[2]; 12 | var marginLeft = system.args[3]; 13 | var marginTop = system.args[4]; 14 | var marginRight = system.args[5]; 15 | var marginBottom = system.args[6]; 16 | page.viewportSize = { width: 600, height: 600 }; 17 | page.paperSize = { 18 | format: 'A4', 19 | margin: { 20 | left: marginLeft, 21 | top: marginTop, 22 | right: marginRight, 23 | bottom: marginBottom 24 | } 25 | }; 26 | page.open(address, function (status) { 27 | if (status !== 'success') { 28 | console.log('Unable to load the address!'); 29 | } else { 30 | window.setTimeout(function () { 31 | page.render(output); 32 | phantom.exit(); 33 | }, 200); 34 | } 35 | }); 36 | } 37 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/rasterize.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(), 3 | system = require('system'), 4 | address, output, size; 5 | 6 | if (system.args.length < 3 || system.args.length > 5) { 7 | console.log('Usage: rasterize.js URL filename [paperwidth*paperheight|paperformat] [zoom]'); 8 | console.log(' paper (pdf output) examples: "5in*7.5in", "10cm*20cm", "A4", "Letter"'); 9 | console.log(' image (png/jpg output) examples: "1920px" entire page, window width 1920px'); 10 | console.log(' "800px*600px" window, clipped to 800x600'); 11 | phantom.exit(1); 12 | } else { 13 | address = system.args[1]; 14 | output = system.args[2]; 15 | page.viewportSize = { width: 600, height: 600 }; 16 | if (system.args.length > 3 && system.args[2].substr(-4) === ".pdf") { 17 | size = system.args[3].split('*'); 18 | page.paperSize = size.length === 2 ? { width: size[0], height: size[1], margin: '0px' } 19 | : { format: system.args[3], orientation: 'portrait', margin: '1cm' }; 20 | } else if (system.args.length > 3 && system.args[3].substr(-2) === "px") { 21 | size = system.args[3].split('*'); 22 | if (size.length === 2) { 23 | pageWidth = parseInt(size[0], 10); 24 | pageHeight = parseInt(size[1], 10); 25 | page.viewportSize = { width: pageWidth, height: pageHeight }; 26 | page.clipRect = { top: 0, left: 0, width: pageWidth, height: pageHeight }; 27 | } else { 28 | console.log("size:", system.args[3]); 29 | pageWidth = parseInt(system.args[3], 10); 30 | pageHeight = parseInt(pageWidth * 3/4, 10); // it's as good an assumption as any 31 | console.log ("pageHeight:",pageHeight); 32 | page.viewportSize = { width: pageWidth, height: pageHeight }; 33 | } 34 | } 35 | if (system.args.length > 4) { 36 | page.zoomFactor = system.args[4]; 37 | } 38 | page.open(address, function (status) { 39 | if (status !== 'success') { 40 | console.log('Unable to load the address!'); 41 | phantom.exit(1); 42 | } else { 43 | window.setTimeout(function () { 44 | page.render(output); 45 | phantom.exit(); 46 | }, 200); 47 | } 48 | }); 49 | } 50 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/render_multi_url.js: -------------------------------------------------------------------------------- 1 | // Render Multiple URLs to file 2 | 3 | "use strict"; 4 | var RenderUrlsToFile, arrayOfUrls, system; 5 | 6 | system = require("system"); 7 | 8 | /* 9 | Render given urls 10 | @param array of URLs to render 11 | @param callbackPerUrl Function called after finishing each URL, including the last URL 12 | @param callbackFinal Function called after finishing everything 13 | */ 14 | RenderUrlsToFile = function(urls, callbackPerUrl, callbackFinal) { 15 | var getFilename, next, page, retrieve, urlIndex, webpage; 16 | urlIndex = 0; 17 | webpage = require("webpage"); 18 | page = null; 19 | getFilename = function() { 20 | return "rendermulti-" + urlIndex + ".png"; 21 | }; 22 | next = function(status, url, file) { 23 | page.close(); 24 | callbackPerUrl(status, url, file); 25 | return retrieve(); 26 | }; 27 | retrieve = function() { 28 | var url; 29 | if (urls.length > 0) { 30 | url = urls.shift(); 31 | urlIndex++; 32 | page = webpage.create(); 33 | page.viewportSize = { 34 | width: 800, 35 | height: 600 36 | }; 37 | page.settings.userAgent = "Phantom.js bot"; 38 | return page.open("http://" + url, function(status) { 39 | var file; 40 | file = getFilename(); 41 | if (status === "success") { 42 | return window.setTimeout((function() { 43 | page.render(file); 44 | return next(status, url, file); 45 | }), 200); 46 | } else { 47 | return next(status, url, file); 48 | } 49 | }); 50 | } else { 51 | return callbackFinal(); 52 | } 53 | }; 54 | return retrieve(); 55 | }; 56 | 57 | arrayOfUrls = null; 58 | 59 | if (system.args.length > 1) { 60 | arrayOfUrls = Array.prototype.slice.call(system.args, 1); 61 | } else { 62 | console.log("Usage: phantomjs render_multi_url.js [domain.name1, domain.name2, ...]"); 63 | arrayOfUrls = ["www.google.com", "www.bbc.co.uk", "phantomjs.org"]; 64 | } 65 | 66 | RenderUrlsToFile(arrayOfUrls, (function(status, url, file) { 67 | if (status !== "success") { 68 | return console.log("Unable to render '" + url + "'"); 69 | } else { 70 | return console.log("Rendered '" + url + "' at '" + file + "'"); 71 | } 72 | }), function() { 73 | return phantom.exit(); 74 | }); 75 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/responsive-screenshot.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Captures the full height document even if it's not showing on the screen or captures with the provided range of screen sizes. 3 | * 4 | * A basic example for taking a screen shot using phantomjs which is sampled for https://nodejs-dersleri.github.io/ 5 | * 6 | * usage : phantomjs responsive-screenshot.js {url} [output format] [doClipping] 7 | * 8 | * examples > 9 | * phantomjs responsive-screenshot.js https://nodejs-dersleri.github.io/ 10 | * phantomjs responsive-screenshot.js https://nodejs-dersleri.github.io/ pdf 11 | * phantomjs responsive-screenshot.js https://nodejs-dersleri.github.io/ true 12 | * phantomjs responsive-screenshot.js https://nodejs-dersleri.github.io/ png true 13 | * 14 | * @author Salih sagdilek 15 | */ 16 | 17 | /** 18 | * http://phantomjs.org/api/system/property/args.html 19 | * 20 | * Queries and returns a list of the command-line arguments. 21 | * The first one is always the script name, which is then followed by the subsequent arguments. 22 | */ 23 | var args = require('system').args; 24 | /** 25 | * http://phantomjs.org/api/fs/ 26 | * 27 | * file system api 28 | */ 29 | var fs = require('fs'); 30 | 31 | /** 32 | * http://phantomjs.org/api/webpage/ 33 | * 34 | * Web page api 35 | */ 36 | var page = new WebPage(); 37 | 38 | /** 39 | * if url address does not exist, exit phantom 40 | */ 41 | if ( 1 === args.length ) { 42 | console.log('Url address is required'); 43 | phantom.exit(); 44 | } 45 | 46 | /** 47 | * setup url address (second argument); 48 | */ 49 | var urlAddress = args[1].toLowerCase(); 50 | 51 | 52 | /** 53 | * set output extension format 54 | * @type {*} 55 | */ 56 | var ext = getFileExtension(); 57 | 58 | /** 59 | * set if clipping ? 60 | * @type {boolean} 61 | */ 62 | var clipping = getClipping(); 63 | 64 | /** 65 | * setup viewports 66 | */ 67 | var viewports = [ 68 | { 69 | width : 1200, 70 | height : 800 71 | }, 72 | { 73 | width : 1024, 74 | height : 768 75 | }, 76 | { 77 | width : 768, 78 | height : 1024 79 | }, 80 | { 81 | width : 480, 82 | height : 640 83 | }, 84 | { 85 | width : 320, 86 | height : 480 87 | } 88 | ]; 89 | 90 | page.open(urlAddress, function (status) { 91 | if ( 'success' !== status ) { 92 | console.log('Unable to load the url address!'); 93 | } else { 94 | var folder = urlToDir(urlAddress); 95 | var output, key; 96 | 97 | function render(n) { 98 | if ( !!n ) { 99 | key = n - 1; 100 | page.viewportSize = viewports[key]; 101 | if ( clipping ) { 102 | page.clipRect = viewports[key]; 103 | } 104 | output = folder + "/" + getFileName(viewports[key]); 105 | console.log('Saving ' + output); 106 | page.render(output); 107 | render(key); 108 | } 109 | } 110 | 111 | render(viewports.length); 112 | } 113 | phantom.exit(); 114 | }); 115 | 116 | /** 117 | * filename generator helper 118 | * @param viewport 119 | * @returns {string} 120 | */ 121 | function getFileName(viewport) { 122 | var d = new Date(); 123 | var date = [ 124 | d.getUTCFullYear(), 125 | d.getUTCMonth() + 1, 126 | d.getUTCDate() 127 | ]; 128 | var time = [ 129 | d.getHours() <= 9 ? '0' + d.getHours() : d.getHours(), 130 | d.getMinutes() <= 9 ? '0' + d.getMinutes() : d.getMinutes(), 131 | d.getSeconds() <= 9 ? '0' + d.getSeconds() : d.getSeconds(), 132 | d.getMilliseconds() 133 | ]; 134 | var resolution = viewport.width + (clipping ? "x" + viewport.height : ''); 135 | 136 | return date.join('-') + '_' + time.join('-') + "_" + resolution + ext; 137 | } 138 | 139 | /** 140 | * output extension format helper 141 | * 142 | * @returns {*} 143 | */ 144 | function getFileExtension() { 145 | if ( 'true' != args[2] && !!args[2] ) { 146 | return '.' + args[2]; 147 | } 148 | return '.png'; 149 | } 150 | 151 | /** 152 | * check if clipping 153 | * 154 | * @returns {boolean} 155 | */ 156 | function getClipping() { 157 | if ( 'true' == args[3] ) { 158 | return !!args[3]; 159 | } else if ( 'true' == args[2] ) { 160 | return !!args[2]; 161 | } 162 | return false; 163 | } 164 | 165 | /** 166 | * url to directory helper 167 | * 168 | * @param url 169 | * @returns {string} 170 | */ 171 | function urlToDir(url) { 172 | var dir = url 173 | .replace(/^(http|https):\/\//, '') 174 | .replace(/\/$/, ''); 175 | 176 | if ( !fs.makeTree(dir) ) { 177 | console.log('"' + dir + '" is NOT created.'); 178 | phantom.exit(); 179 | } 180 | return dir; 181 | } 182 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/run-jasmine.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | 4 | /** 5 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 6 | * on a server response or for a ui change (fadeIn, etc.) to occur. 7 | * 8 | * @param testFx javascript condition that evaluates to a boolean, 9 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 10 | * as a callback function. 11 | * @param onReady what to do when testFx condition is fulfilled, 12 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 13 | * as a callback function. 14 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 15 | */ 16 | function waitFor(testFx, onReady, timeOutMillis) { 17 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timeout is 3s 18 | start = new Date().getTime(), 19 | condition = false, 20 | interval = setInterval(function() { 21 | if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { 22 | // If not time-out yet and condition not yet fulfilled 23 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 24 | } else { 25 | if(!condition) { 26 | // If condition still not fulfilled (timeout but condition is 'false') 27 | console.log("'waitFor()' timeout"); 28 | phantom.exit(1); 29 | } else { 30 | // Condition fulfilled (timeout and/or condition is 'true') 31 | console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); 32 | typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 33 | clearInterval(interval); //< Stop this interval 34 | } 35 | } 36 | }, 100); //< repeat check every 100ms 37 | }; 38 | 39 | 40 | if (system.args.length !== 2) { 41 | console.log('Usage: run-jasmine.js URL'); 42 | phantom.exit(1); 43 | } 44 | 45 | var page = require('webpage').create(); 46 | 47 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 48 | page.onConsoleMessage = function(msg) { 49 | console.log(msg); 50 | }; 51 | 52 | page.open(system.args[1], function(status){ 53 | if (status !== "success") { 54 | console.log("Unable to open " + system.args[1]); 55 | phantom.exit(1); 56 | } else { 57 | waitFor(function(){ 58 | return page.evaluate(function(){ 59 | return document.body.querySelector('.symbolSummary .pending') === null 60 | }); 61 | }, function(){ 62 | var exitCode = page.evaluate(function(){ 63 | try { 64 | console.log(''); 65 | console.log(document.body.querySelector('.description').innerText); 66 | var list = document.body.querySelectorAll('.results > #details > .specDetail.failed'); 67 | if (list && list.length > 0) { 68 | console.log(''); 69 | console.log(list.length + ' test(s) FAILED:'); 70 | for (i = 0; i < list.length; ++i) { 71 | var el = list[i], 72 | desc = el.querySelector('.description'), 73 | msg = el.querySelector('.resultMessage.fail'); 74 | console.log(''); 75 | console.log(desc.innerText); 76 | console.log(msg.innerText); 77 | console.log(''); 78 | } 79 | return 1; 80 | } else { 81 | console.log(document.body.querySelector('.alert > .passingAlert.bar').innerText); 82 | return 0; 83 | } 84 | } catch (ex) { 85 | console.log(ex); 86 | return 1; 87 | } 88 | }); 89 | phantom.exit(exitCode); 90 | }); 91 | } 92 | }); 93 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/run-jasmine2.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | 4 | /** 5 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 6 | * on a server response or for a ui change (fadeIn, etc.) to occur. 7 | * 8 | * @param testFx javascript condition that evaluates to a boolean, 9 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 10 | * as a callback function. 11 | * @param onReady what to do when testFx condition is fulfilled, 12 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 13 | * as a callback function. 14 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 15 | */ 16 | function waitFor(testFx, onReady, timeOutMillis) { 17 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timeout is 3s 18 | start = new Date().getTime(), 19 | condition = false, 20 | interval = setInterval(function() { 21 | if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { 22 | // If not time-out yet and condition not yet fulfilled 23 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 24 | } else { 25 | if(!condition) { 26 | // If condition still not fulfilled (timeout but condition is 'false') 27 | console.log("'waitFor()' timeout"); 28 | phantom.exit(1); 29 | } else { 30 | // Condition fulfilled (timeout and/or condition is 'true') 31 | console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); 32 | typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 33 | clearInterval(interval); //< Stop this interval 34 | } 35 | } 36 | }, 100); //< repeat check every 100ms 37 | }; 38 | 39 | 40 | if (system.args.length !== 2) { 41 | console.log('Usage: run-jasmine2.js URL'); 42 | phantom.exit(1); 43 | } 44 | 45 | var page = require('webpage').create(); 46 | 47 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 48 | page.onConsoleMessage = function(msg) { 49 | console.log(msg); 50 | }; 51 | 52 | page.open(system.args[1], function(status){ 53 | if (status !== "success") { 54 | console.log("Unable to access network"); 55 | phantom.exit(); 56 | } else { 57 | waitFor(function(){ 58 | return page.evaluate(function(){ 59 | return (document.body.querySelector('.symbolSummary .pending') === null && 60 | document.body.querySelector('.duration') !== null); 61 | }); 62 | }, function(){ 63 | var exitCode = page.evaluate(function(){ 64 | console.log(''); 65 | 66 | var title = 'Jasmine'; 67 | var version = document.body.querySelector('.version').innerText; 68 | var duration = document.body.querySelector('.duration').innerText; 69 | var banner = title + ' ' + version + ' ' + duration; 70 | console.log(banner); 71 | 72 | var list = document.body.querySelectorAll('.results > .failures > .spec-detail.failed'); 73 | if (list && list.length > 0) { 74 | console.log(''); 75 | console.log(list.length + ' test(s) FAILED:'); 76 | for (i = 0; i < list.length; ++i) { 77 | var el = list[i], 78 | desc = el.querySelector('.description'), 79 | msg = el.querySelector('.messages > .result-message'); 80 | console.log(''); 81 | console.log(desc.innerText); 82 | console.log(msg.innerText); 83 | console.log(''); 84 | } 85 | return 1; 86 | } else { 87 | console.log(document.body.querySelector('.alert > .bar.passed,.alert > .bar.skipped').innerText); 88 | return 0; 89 | } 90 | }); 91 | phantom.exit(exitCode); 92 | }); 93 | } 94 | }); 95 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/run-qunit.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | 4 | /** 5 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 6 | * on a server response or for a ui change (fadeIn, etc.) to occur. 7 | * 8 | * @param testFx javascript condition that evaluates to a boolean, 9 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 10 | * as a callback function. 11 | * @param onReady what to do when testFx condition is fulfilled, 12 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 13 | * as a callback function. 14 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 15 | */ 16 | function waitFor(testFx, onReady, timeOutMillis) { 17 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3001, //< Default Max Timout is 3s 18 | start = new Date().getTime(), 19 | condition = false, 20 | interval = setInterval(function() { 21 | if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { 22 | // If not time-out yet and condition not yet fulfilled 23 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 24 | } else { 25 | if(!condition) { 26 | // If condition still not fulfilled (timeout but condition is 'false') 27 | console.log("'waitFor()' timeout"); 28 | phantom.exit(1); 29 | } else { 30 | // Condition fulfilled (timeout and/or condition is 'true') 31 | console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); 32 | typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 33 | clearInterval(interval); //< Stop this interval 34 | } 35 | } 36 | }, 100); //< repeat check every 250ms 37 | }; 38 | 39 | 40 | if (system.args.length !== 2) { 41 | console.log('Usage: run-qunit.js URL'); 42 | phantom.exit(1); 43 | } 44 | 45 | var page = require('webpage').create(); 46 | 47 | // Route "console.log()" calls from within the Page context to the main Phantom context (i.e. current "this") 48 | page.onConsoleMessage = function(msg) { 49 | console.log(msg); 50 | }; 51 | 52 | page.open(system.args[1], function(status){ 53 | if (status !== "success") { 54 | console.log("Unable to access network"); 55 | phantom.exit(1); 56 | } else { 57 | waitFor(function(){ 58 | return page.evaluate(function(){ 59 | var el = document.getElementById('qunit-testresult'); 60 | if (el && el.innerText.match('completed')) { 61 | return true; 62 | } 63 | return false; 64 | }); 65 | }, function(){ 66 | var failedNum = page.evaluate(function(){ 67 | var el = document.getElementById('qunit-testresult'); 68 | console.log(el.innerText); 69 | try { 70 | return el.getElementsByClassName('failed')[0].innerHTML; 71 | } catch (e) { } 72 | return 10000; 73 | }); 74 | phantom.exit((parseInt(failedNum, 10) > 0) ? 1 : 0); 75 | }); 76 | } 77 | }); 78 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/scandir.js: -------------------------------------------------------------------------------- 1 | // List all the files in a Tree of Directories 2 | 3 | "use strict"; 4 | var system = require('system'); 5 | 6 | if (system.args.length !== 2) { 7 | console.log("Usage: phantomjs scandir.js DIRECTORY_TO_SCAN"); 8 | phantom.exit(1); 9 | } 10 | 11 | var scanDirectory = function (path) { 12 | var fs = require('fs'); 13 | if (fs.exists(path) && fs.isFile(path)) { 14 | console.log(path); 15 | } else if (fs.isDirectory(path)) { 16 | fs.list(path).forEach(function (e) { 17 | if ( e !== "." && e !== ".." ) { //< Avoid loops 18 | scanDirectory(path + '/' + e); 19 | } 20 | }); 21 | } 22 | }; 23 | scanDirectory(system.args[1]); 24 | phantom.exit(); 25 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/server.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(); 3 | var server = require('webserver').create(); 4 | var system = require('system'); 5 | var host, port; 6 | 7 | if (system.args.length !== 2) { 8 | console.log('Usage: server.js '); 9 | phantom.exit(1); 10 | } else { 11 | port = system.args[1]; 12 | var listening = server.listen(port, function (request, response) { 13 | console.log("GOT HTTP REQUEST"); 14 | console.log(JSON.stringify(request, null, 4)); 15 | 16 | // we set the headers here 17 | response.statusCode = 200; 18 | response.headers = {"Cache": "no-cache", "Content-Type": "text/html"}; 19 | // this is also possible: 20 | response.setHeader("foo", "bar"); 21 | // now we write the body 22 | // note: the headers above will now be sent implictly 23 | response.write("YES!"); 24 | // note: writeBody can be called multiple times 25 | response.write("

pretty cool :)"); 26 | response.close(); 27 | }); 28 | if (!listening) { 29 | console.log("could not create web server listening on port " + port); 30 | phantom.exit(); 31 | } 32 | var url = "http://localhost:" + port + "/foo/bar.php?asdf=true"; 33 | console.log("SENDING REQUEST TO:"); 34 | console.log(url); 35 | page.open(url, function (status) { 36 | if (status !== 'success') { 37 | console.log('FAIL to load the address'); 38 | } else { 39 | console.log("GOT REPLY FROM SERVER:"); 40 | console.log(page.content); 41 | } 42 | phantom.exit(); 43 | }); 44 | } 45 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/serverkeepalive.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var port, server, service, 3 | system = require('system'); 4 | 5 | if (system.args.length !== 2) { 6 | console.log('Usage: serverkeepalive.js '); 7 | phantom.exit(1); 8 | } else { 9 | port = system.args[1]; 10 | server = require('webserver').create(); 11 | 12 | service = server.listen(port, { keepAlive: true }, function (request, response) { 13 | console.log('Request at ' + new Date()); 14 | console.log(JSON.stringify(request, null, 4)); 15 | 16 | var body = JSON.stringify(request, null, 4); 17 | response.statusCode = 200; 18 | response.headers = { 19 | 'Cache': 'no-cache', 20 | 'Content-Type': 'text/plain', 21 | 'Connection': 'Keep-Alive', 22 | 'Keep-Alive': 'timeout=5, max=100', 23 | 'Content-Length': body.length 24 | }; 25 | response.write(body); 26 | response.close(); 27 | }); 28 | 29 | if (service) { 30 | console.log('Web server running on port ' + port); 31 | } else { 32 | console.log('Error: Could not create web server listening on port ' + port); 33 | phantom.exit(); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/simpleserver.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var port, server, service, 3 | system = require('system'); 4 | 5 | if (system.args.length !== 2) { 6 | console.log('Usage: simpleserver.js '); 7 | phantom.exit(1); 8 | } else { 9 | port = system.args[1]; 10 | server = require('webserver').create(); 11 | 12 | service = server.listen(port, function (request, response) { 13 | 14 | console.log('Request at ' + new Date()); 15 | console.log(JSON.stringify(request, null, 4)); 16 | 17 | response.statusCode = 200; 18 | response.headers = { 19 | 'Cache': 'no-cache', 20 | 'Content-Type': 'text/html' 21 | }; 22 | response.write(''); 23 | response.write(''); 24 | response.write('Hello, world!'); 25 | response.write(''); 26 | response.write(''); 27 | response.write('

This is from PhantomJS web server.

'); 28 | response.write('

Request data:

'); 29 | response.write('
');
30 |         response.write(JSON.stringify(request, null, 4));
31 |         response.write('
'); 32 | response.write(''); 33 | response.write(''); 34 | response.close(); 35 | }); 36 | 37 | if (service) { 38 | console.log('Web server running on port ' + port); 39 | } else { 40 | console.log('Error: Could not create web server listening on port ' + port); 41 | phantom.exit(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/sleepsort.js: -------------------------------------------------------------------------------- 1 | // sleepsort.js - Sort integers from the commandline in a very ridiculous way: leveraging timeouts :P 2 | 3 | "use strict"; 4 | var system = require('system'); 5 | 6 | function sleepSort(array, callback) { 7 | var sortedCount = 0, 8 | i, len; 9 | for ( i = 0, len = array.length; i < len; ++i ) { 10 | setTimeout((function(j){ 11 | return function() { 12 | console.log(array[j]); 13 | ++sortedCount; 14 | (len === sortedCount) && callback(); 15 | }; 16 | }(i)), array[i]); 17 | } 18 | } 19 | 20 | if ( system.args.length < 2 ) { 21 | console.log("Usage: phantomjs sleepsort.js PUT YOUR INTEGERS HERE SEPARATED BY SPACES"); 22 | phantom.exit(1); 23 | } else { 24 | sleepSort(system.args.slice(1), function() { 25 | phantom.exit(); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/stdin-stdout-stderr.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var system = require('system'); 3 | 4 | system.stdout.write('Hello, system.stdout.write!'); 5 | system.stdout.writeLine('\nHello, system.stdout.writeLine!'); 6 | 7 | system.stderr.write('Hello, system.stderr.write!'); 8 | system.stderr.writeLine('\nHello, system.stderr.writeLine!'); 9 | 10 | system.stdout.writeLine('system.stdin.readLine(): '); 11 | var line = system.stdin.readLine(); 12 | system.stdout.writeLine(JSON.stringify(line)); 13 | 14 | // This is essentially a `readAll` 15 | system.stdout.writeLine('system.stdin.read(5): (ctrl+D to end)'); 16 | var input = system.stdin.read(5); 17 | system.stdout.writeLine(JSON.stringify(input)); 18 | 19 | phantom.exit(0); 20 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/universe.js: -------------------------------------------------------------------------------- 1 | // This is to be used by "module.js" (and "module.coffee") example(s). 2 | // There should NOT be a "universe.coffee" as only 1 of the 2 would 3 | // ever be loaded unless the file extension was specified. 4 | 5 | "use strict"; 6 | exports.answer = 42; 7 | 8 | exports.start = function () { 9 | console.log('Starting the universe....'); 10 | } 11 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/unrandomize.js: -------------------------------------------------------------------------------- 1 | // Modify global object at the page initialization. 2 | // In this example, effectively Math.random() always returns 0.42. 3 | 4 | "use strict"; 5 | var page = require('webpage').create(); 6 | 7 | page.onInitialized = function () { 8 | page.evaluate(function () { 9 | Math.random = function() { 10 | return 42 / 100; 11 | }; 12 | }); 13 | }; 14 | 15 | page.open('http://ariya.github.com/js/random/', function (status) { 16 | var result; 17 | if (status !== 'success') { 18 | console.log('Network error.'); 19 | } else { 20 | console.log(page.evaluate(function () { 21 | return document.getElementById('numbers').textContent; 22 | })); 23 | } 24 | phantom.exit(); 25 | }); 26 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/useragent.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var page = require('webpage').create(); 3 | console.log('The default user agent is ' + page.settings.userAgent); 4 | page.settings.userAgent = 'SpecialAgent'; 5 | page.open('http://www.httpuseragent.org', function (status) { 6 | if (status !== 'success') { 7 | console.log('Unable to access network'); 8 | } else { 9 | var ua = page.evaluate(function () { 10 | return document.getElementById('myagent').innerText; 11 | }); 12 | console.log(ua); 13 | } 14 | phantom.exit(); 15 | }); 16 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/version.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | console.log('using PhantomJS version ' + 3 | phantom.version.major + '.' + 4 | phantom.version.minor + '.' + 5 | phantom.version.patch); 6 | phantom.exit(); 7 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/waitfor.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Wait until the test condition is true or a timeout occurs. Useful for waiting 3 | * on a server response or for a ui change (fadeIn, etc.) to occur. 4 | * 5 | * @param testFx javascript condition that evaluates to a boolean, 6 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 7 | * as a callback function. 8 | * @param onReady what to do when testFx condition is fulfilled, 9 | * it can be passed in as a string (e.g.: "1 == 1" or "$('#bar').is(':visible')" or 10 | * as a callback function. 11 | * @param timeOutMillis the max amount of time to wait. If not specified, 3 sec is used. 12 | */ 13 | 14 | "use strict"; 15 | function waitFor(testFx, onReady, timeOutMillis) { 16 | var maxtimeOutMillis = timeOutMillis ? timeOutMillis : 3000, //< Default Max Timout is 3s 17 | start = new Date().getTime(), 18 | condition = false, 19 | interval = setInterval(function() { 20 | if ( (new Date().getTime() - start < maxtimeOutMillis) && !condition ) { 21 | // If not time-out yet and condition not yet fulfilled 22 | condition = (typeof(testFx) === "string" ? eval(testFx) : testFx()); //< defensive code 23 | } else { 24 | if(!condition) { 25 | // If condition still not fulfilled (timeout but condition is 'false') 26 | console.log("'waitFor()' timeout"); 27 | phantom.exit(1); 28 | } else { 29 | // Condition fulfilled (timeout and/or condition is 'true') 30 | console.log("'waitFor()' finished in " + (new Date().getTime() - start) + "ms."); 31 | typeof(onReady) === "string" ? eval(onReady) : onReady(); //< Do what it's supposed to do once the condition is fulfilled 32 | clearInterval(interval); //< Stop this interval 33 | } 34 | } 35 | }, 250); //< repeat check every 250ms 36 | }; 37 | 38 | 39 | var page = require('webpage').create(); 40 | 41 | // Open Twitter on 'sencha' profile and, onPageLoad, do... 42 | page.open("http://twitter.com/#!/sencha", function (status) { 43 | // Check for page load success 44 | if (status !== "success") { 45 | console.log("Unable to access network"); 46 | } else { 47 | // Wait for 'signin-dropdown' to be visible 48 | waitFor(function() { 49 | // Check in the page if a specific element is now visible 50 | return page.evaluate(function() { 51 | return $("#signin-dropdown").is(":visible"); 52 | }); 53 | }, function() { 54 | console.log("The sign-in dialog should be visible now."); 55 | phantom.exit(); 56 | }); 57 | } 58 | }); 59 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/examples/walk_through_frames.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var p = require("webpage").create(); 3 | 4 | function pageTitle(page) { 5 | return page.evaluate(function(){ 6 | return window.document.title; 7 | }); 8 | } 9 | 10 | function setPageTitle(page, newTitle) { 11 | page.evaluate(function(newTitle){ 12 | window.document.title = newTitle; 13 | }, newTitle); 14 | } 15 | 16 | p.open("../test/webpage-spec-frames/index.html", function(status) { 17 | console.log("pageTitle(): " + pageTitle(p)); 18 | console.log("currentFrameName(): "+p.currentFrameName()); 19 | console.log("childFramesCount(): "+p.childFramesCount()); 20 | console.log("childFramesName(): "+p.childFramesName()); 21 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 22 | console.log(""); 23 | 24 | console.log("p.switchToChildFrame(\"frame1\"): "+p.switchToChildFrame("frame1")); 25 | console.log("pageTitle(): " + pageTitle(p)); 26 | console.log("currentFrameName(): "+p.currentFrameName()); 27 | console.log("childFramesCount(): "+p.childFramesCount()); 28 | console.log("childFramesName(): "+p.childFramesName()); 29 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 30 | console.log(""); 31 | 32 | console.log("p.switchToChildFrame(\"frame1-2\"): "+p.switchToChildFrame("frame1-2")); 33 | console.log("pageTitle(): " + pageTitle(p)); 34 | console.log("currentFrameName(): "+p.currentFrameName()); 35 | console.log("childFramesCount(): "+p.childFramesCount()); 36 | console.log("childFramesName(): "+p.childFramesName()); 37 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 38 | console.log(""); 39 | 40 | console.log("p.switchToParentFrame(): "+p.switchToParentFrame()); 41 | console.log("pageTitle(): " + pageTitle(p)); 42 | console.log("currentFrameName(): "+p.currentFrameName()); 43 | console.log("childFramesCount(): "+p.childFramesCount()); 44 | console.log("childFramesName(): "+p.childFramesName()); 45 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 46 | console.log(""); 47 | 48 | console.log("p.switchToChildFrame(0): "+p.switchToChildFrame(0)); 49 | console.log("pageTitle(): " + pageTitle(p)); 50 | console.log("currentFrameName(): "+p.currentFrameName()); 51 | console.log("childFramesCount(): "+p.childFramesCount()); 52 | console.log("childFramesName(): "+p.childFramesName()); 53 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 54 | console.log(""); 55 | 56 | console.log("p.switchToMainFrame()"); p.switchToMainFrame(); 57 | console.log("pageTitle(): " + pageTitle(p)); 58 | console.log("currentFrameName(): "+p.currentFrameName()); 59 | console.log("childFramesCount(): "+p.childFramesCount()); 60 | console.log("childFramesName(): "+p.childFramesName()); 61 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 62 | console.log(""); 63 | 64 | console.log("p.switchToChildFrame(\"frame2\"): "+p.switchToChildFrame("frame2")); 65 | console.log("pageTitle(): " + pageTitle(p)); 66 | console.log("currentFrameName(): "+p.currentFrameName()); 67 | console.log("childFramesCount(): "+p.childFramesCount()); 68 | console.log("childFramesName(): "+p.childFramesName()); 69 | console.log("setPageTitle(CURRENT TITLE+'-visited')"); setPageTitle(p, pageTitle(p) + "-visited"); 70 | console.log(""); 71 | 72 | phantom.exit(); 73 | }); 74 | -------------------------------------------------------------------------------- /libraries/phantomjs-2.1.1-linux-i686/third-party.txt: -------------------------------------------------------------------------------- 1 | This document contains the list of Third Party Software included with 2 | PhantomJS, along with the license information. 3 | 4 | Third Party Software may impose additional restrictions and it is the 5 | user's responsibility to ensure that they have met the licensing 6 | requirements of PhantomJS and the relevant license of the Third Party 7 | Software they are using. 8 | 9 | Qt - http://qt-project.org/ 10 | License: GNU Lesser General Public License (LGPL) version 2.1. 11 | Reference: http://qt-project.org/doc/qt-4.8/lgpl.html. 12 | 13 | WebKit - http://www.webkit.org/ 14 | License: GNU Lesser General Public License (LGPL) version 2.1 and BSD. 15 | Reference: http://www.webkit.org/coding/lgpl-license.html and 16 | http://www.webkit.org/coding/bsd-license.html. 17 | 18 | Mongoose - https://github.com/cesanta/mongoose 19 | License: MIT 20 | Reference: https://github.com/cesanta/mongoose/commit/abbf27338ef554cce0281ac157aa71a9c1b82a55 21 | 22 | OpenSSL - http://www.openssl.org/ 23 | License: OpenSSL License, SSLeay License. 24 | Reference: http://www.openssl.org/source/license.html. 25 | 26 | Linenoise - https://github.com/tadmarshall/linenoise 27 | License: BSD. 28 | Reference: https://github.com/tadmarshall/linenoise/blob/master/linenoise.h. 29 | 30 | QCommandLine - http://xf.iksaif.net/dev/qcommandline.html 31 | License: GNU Lesser General Public License (LGPL) version 2.1. 32 | Reference: http://dev.iksaif.net/projects/qcommandline/repository/revisions/master/entry/COPYING 33 | 34 | wkhtmlpdf - http://code.google.com/p/wkhtmltopdf/ 35 | License: GNU Lesser General Public License (LGPL) 36 | Reference: http://code.google.com/p/wkhtmltopdf/ 37 | -------------------------------------------------------------------------------- /libraries/readability/JSLikeHTMLElement.php: -------------------------------------------------------------------------------- 1 | registerNodeClass('DOMElement', 'JSLikeHTMLElement'); 16 | * $doc->loadHTML('

Para 1

Para 2

'); 17 | * $elem = $doc->getElementsByTagName('div')->item(0); 18 | * 19 | * // print innerHTML 20 | * echo $elem->innerHTML; // prints '

Para 1

Para 2

' 21 | * echo "\n\n"; 22 | * 23 | * // set innerHTML 24 | * $elem->innerHTML = 'FiveFilters.org'; 25 | * echo $elem->innerHTML; // prints 'FiveFilters.org' 26 | * echo "\n\n"; 27 | * 28 | * // print document (with our changes) 29 | * echo $doc->saveXML(); 30 | * @endcode 31 | * 32 | * @author Keyvan Minoukadeh - http://www.keyvan.net - keyvan@keyvan.net 33 | * @see http://fivefilters.org (the project this was written for) 34 | */ 35 | class JSLikeHTMLElement extends DOMElement 36 | { 37 | /** 38 | * Used for setting innerHTML like it's done in JavaScript: 39 | * @code 40 | * $div->innerHTML = '

Chapter 2

The story begins...

'; 41 | * @endcode 42 | */ 43 | public function __set($name, $value) { 44 | if ($name == 'innerHTML') { 45 | // first, empty the element 46 | for ($x=$this->childNodes->length-1; $x>=0; $x--) { 47 | $this->removeChild($this->childNodes->item($x)); 48 | } 49 | // $value holds our new inner HTML 50 | if ($value != '') { 51 | $f = $this->ownerDocument->createDocumentFragment(); 52 | // appendXML() expects well-formed markup (XHTML) 53 | $result = @$f->appendXML($value); // @ to suppress PHP warnings 54 | if ($result) { 55 | if ($f->hasChildNodes()) $this->appendChild($f); 56 | } else { 57 | // $value is probably ill-formed 58 | $f = new DOMDocument(); 59 | if (function_exists('mb_convert_encoding')) { 60 | //$value = mb_convert_encoding($value, 'HTML-ENTITIES', 'UTF-8'); 61 | } 62 | // Using will generate a warning, but so will bad HTML 63 | // (and by this point, bad HTML is what we've got). 64 | // We use it (and suppress the warning) because an HTML fragment will 65 | // be wrapped around tags which we don't really want to keep. 66 | // Note: despite the warning, if loadHTML succeeds it will return true. 67 | $result = @$f->loadHTML(''.$value.''); 68 | if ($result) { 69 | $import = $f->getElementsByTagName('htmlfragment')->item(0); 70 | foreach ($import->childNodes as $child) { 71 | $importedNode = $this->ownerDocument->importNode($child, true); 72 | $this->appendChild($importedNode); 73 | } 74 | } else { 75 | // oh well, we tried, we really did. :( 76 | // this element is now empty 77 | } 78 | } 79 | } 80 | } else { 81 | $trace = debug_backtrace(); 82 | trigger_error('Undefined property via __set(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); 83 | } 84 | } 85 | 86 | /** 87 | * Used for getting innerHTML like it's done in JavaScript: 88 | * @code 89 | * $string = $div->innerHTML; 90 | * @endcode 91 | */ 92 | public function __get($name) 93 | { 94 | if ($name == 'innerHTML') { 95 | $inner = ''; 96 | foreach ($this->childNodes as $child) { 97 | $inner .= $this->ownerDocument->saveXML($child); 98 | } 99 | return $inner; 100 | } 101 | 102 | $trace = debug_backtrace(); 103 | trigger_error('Undefined property via __get(): '.$name.' in '.$trace[0]['file'].' on line '.$trace[0]['line'], E_USER_NOTICE); 104 | return null; 105 | } 106 | 107 | public function __toString() 108 | { 109 | return '['.$this->tagName.']'; 110 | } 111 | } 112 | ?> -------------------------------------------------------------------------------- /libraries/simplepie/LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2004-2007, Ryan Parman and Geoffrey Sneddon. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are 5 | permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this list of 8 | conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, this list 11 | of conditions and the following disclaimer in the documentation and/or other materials 12 | provided with the distribution. 13 | 14 | * Neither the name of the SimplePie Team nor the names of its contributors may be used 15 | to endorse or promote products derived from this software without specific prior 16 | written permission. 17 | 18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS 19 | OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 20 | AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 21 | AND CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 25 | OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26 | POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie.php: -------------------------------------------------------------------------------- 1 | name = $name; 57 | $this->link = $link; 58 | $this->email = $email; 59 | } 60 | 61 | public function __toString() 62 | { 63 | // There is no $this->data here 64 | return md5(serialize($this)); 65 | } 66 | 67 | public function get_name() 68 | { 69 | if ($this->name !== null) 70 | { 71 | return $this->name; 72 | } 73 | else 74 | { 75 | return null; 76 | } 77 | } 78 | 79 | public function get_link() 80 | { 81 | if ($this->link !== null) 82 | { 83 | return $this->link; 84 | } 85 | else 86 | { 87 | return null; 88 | } 89 | } 90 | 91 | public function get_email() 92 | { 93 | if ($this->email !== null) 94 | { 95 | return $this->email; 96 | } 97 | else 98 | { 99 | return null; 100 | } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Cache.php: -------------------------------------------------------------------------------- 1 | 'SimplePie_Cache_MySQL', 58 | 'memcache' => 'SimplePie_Cache_Memcache', 59 | ); 60 | 61 | /** 62 | * Don't call the constructor. Please. 63 | */ 64 | private function __construct() { } 65 | 66 | /** 67 | * Create a new SimplePie_Cache object 68 | */ 69 | public static function create($location, $filename, $extension) 70 | { 71 | $type = explode(':', $location, 2); 72 | $type = $type[0]; 73 | if (!empty(self::$handlers[$type])) 74 | { 75 | $class = self::$handlers[$type]; 76 | return new $class($location, $filename, $extension); 77 | } 78 | 79 | return new SimplePie_Cache_File($location, $filename, $extension); 80 | } 81 | 82 | /** 83 | * Register a handler 84 | * 85 | * @param string $type DSN type to register for 86 | * @param string $class Name of handler class. Must implement SimplePie_Cache_Base 87 | */ 88 | public static function register($type, $class) 89 | { 90 | self::$handlers[$type] = $class; 91 | } 92 | 93 | /** 94 | * Parse a URL into an array 95 | * 96 | * @param string $url 97 | * @return array 98 | */ 99 | public static function parse_URL($url) 100 | { 101 | $params = parse_url($url); 102 | $params['extras'] = array(); 103 | if (isset($params['query'])) 104 | { 105 | parse_str($params['query'], $params['extras']); 106 | } 107 | return $params; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Cache/Base.php: -------------------------------------------------------------------------------- 1 | get_items(); 51 | $items_by_id = array(); 52 | 53 | if (!empty($items)) 54 | { 55 | foreach ($items as $item) 56 | { 57 | $items_by_id[$item->get_id()] = $item; 58 | } 59 | 60 | if (count($items_by_id) !== count($items)) 61 | { 62 | $items_by_id = array(); 63 | foreach ($items as $item) 64 | { 65 | $items_by_id[$item->get_id(true)] = $item; 66 | } 67 | } 68 | 69 | if (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0])) 70 | { 71 | $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['feed'][0]; 72 | } 73 | elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0])) 74 | { 75 | $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['feed'][0]; 76 | } 77 | elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0])) 78 | { 79 | $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RDF]['RDF'][0]; 80 | } 81 | elseif (isset($data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0])) 82 | { 83 | $channel =& $data->data['child'][SIMPLEPIE_NAMESPACE_RSS_20]['rss'][0]['child'][SIMPLEPIE_NAMESPACE_RSS_20]['channel'][0]; 84 | } 85 | else 86 | { 87 | $channel = null; 88 | } 89 | 90 | if ($channel !== null) 91 | { 92 | if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry'])) 93 | { 94 | unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_10]['entry']); 95 | } 96 | if (isset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry'])) 97 | { 98 | unset($channel['child'][SIMPLEPIE_NAMESPACE_ATOM_03]['entry']); 99 | } 100 | if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item'])) 101 | { 102 | unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_10]['item']); 103 | } 104 | if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item'])) 105 | { 106 | unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_090]['item']); 107 | } 108 | if (isset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item'])) 109 | { 110 | unset($channel['child'][SIMPLEPIE_NAMESPACE_RSS_20]['item']); 111 | } 112 | } 113 | if (isset($data->data['items'])) 114 | { 115 | unset($data->data['items']); 116 | } 117 | if (isset($data->data['ordered_items'])) 118 | { 119 | unset($data->data['ordered_items']); 120 | } 121 | } 122 | return array(serialize($data->data), $items_by_id); 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Cache/File.php: -------------------------------------------------------------------------------- 1 | location = $location; 57 | $this->filename = $filename; 58 | $this->extension = $extension; 59 | $this->name = "$this->location/$this->filename.$this->extension"; 60 | } 61 | 62 | public function save($data) 63 | { 64 | if (file_exists($this->name) && is_writeable($this->name) || file_exists($this->location) && is_writeable($this->location)) 65 | { 66 | if (is_a($data, 'SimplePie')) 67 | { 68 | $data = $data->data; 69 | } 70 | 71 | $data = serialize($data); 72 | return (bool) file_put_contents($this->name, $data); 73 | } 74 | return false; 75 | } 76 | 77 | public function load() 78 | { 79 | if (file_exists($this->name) && is_readable($this->name)) 80 | { 81 | return unserialize(file_get_contents($this->name)); 82 | } 83 | return false; 84 | } 85 | 86 | public function mtime() 87 | { 88 | if (file_exists($this->name)) 89 | { 90 | return filemtime($this->name); 91 | } 92 | return false; 93 | } 94 | 95 | public function touch() 96 | { 97 | if (file_exists($this->name)) 98 | { 99 | return touch($this->name); 100 | } 101 | return false; 102 | } 103 | 104 | public function unlink() 105 | { 106 | if (file_exists($this->name)) 107 | { 108 | return unlink($this->name); 109 | } 110 | return false; 111 | } 112 | } 113 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Cache/Memcache.php: -------------------------------------------------------------------------------- 1 | options = array( 55 | 'host' => '127.0.0.1', 56 | 'port' => 11211, 57 | 'extras' => array( 58 | 'timeout' => 3600, // one hour 59 | 'prefix' => 'simplepie_', 60 | ), 61 | ); 62 | $this->options = array_merge_recursive($this->options, SimplePie_Cache::parse_URL($url)); 63 | $this->name = $this->options['extras']['prefix'] . md5("$filename:$extension"); 64 | 65 | $this->cache = new Memcache(); 66 | $this->cache->addServer($this->options['host'], (int) $this->options['port']); 67 | } 68 | 69 | public function save($data) 70 | { 71 | if (is_a($data, 'SimplePie')) 72 | { 73 | $data = $data->data; 74 | } 75 | return $this->cache->set($this->name, serialize($data), MEMCACHE_COMPRESSED, (int) $this->options['extras']['timeout']); 76 | } 77 | 78 | public function load() 79 | { 80 | $data = $this->cache->get($this->name); 81 | 82 | if ($data !== false) 83 | { 84 | return unserialize($data); 85 | } 86 | return false; 87 | } 88 | 89 | public function mtime() 90 | { 91 | $data = $this->cache->get($this->name); 92 | 93 | if ($data !== false) 94 | { 95 | // essentially ignore the mtime because Memcache expires on it's own 96 | return time(); 97 | } 98 | 99 | return false; 100 | } 101 | 102 | public function touch() 103 | { 104 | $data = $this->cache->get($this->name); 105 | 106 | if ($data !== false) 107 | { 108 | return $this->cache->set($this->name, $data, MEMCACHE_COMPRESSED, (int) $this->duration); 109 | } 110 | 111 | return false; 112 | } 113 | 114 | public function unlink() 115 | { 116 | return $this->cache->delete($this->name); 117 | } 118 | } 119 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Caption.php: -------------------------------------------------------------------------------- 1 | type = $type; 59 | $this->lang = $lang; 60 | $this->startTime = $startTime; 61 | $this->endTime = $endTime; 62 | $this->text = $text; 63 | } 64 | 65 | public function __toString() 66 | { 67 | // There is no $this->data here 68 | return md5(serialize($this)); 69 | } 70 | 71 | public function get_endtime() 72 | { 73 | if ($this->endTime !== null) 74 | { 75 | return $this->endTime; 76 | } 77 | else 78 | { 79 | return null; 80 | } 81 | } 82 | 83 | public function get_language() 84 | { 85 | if ($this->lang !== null) 86 | { 87 | return $this->lang; 88 | } 89 | else 90 | { 91 | return null; 92 | } 93 | } 94 | 95 | public function get_starttime() 96 | { 97 | if ($this->startTime !== null) 98 | { 99 | return $this->startTime; 100 | } 101 | else 102 | { 103 | return null; 104 | } 105 | } 106 | 107 | public function get_text() 108 | { 109 | if ($this->text !== null) 110 | { 111 | return $this->text; 112 | } 113 | else 114 | { 115 | return null; 116 | } 117 | } 118 | 119 | public function get_type() 120 | { 121 | if ($this->type !== null) 122 | { 123 | return $this->type; 124 | } 125 | else 126 | { 127 | return null; 128 | } 129 | } 130 | } 131 | 132 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Category.php: -------------------------------------------------------------------------------- 1 | term = $term; 57 | $this->scheme = $scheme; 58 | $this->label = $label; 59 | } 60 | 61 | public function __toString() 62 | { 63 | // There is no $this->data here 64 | return md5(serialize($this)); 65 | } 66 | 67 | public function get_term() 68 | { 69 | if ($this->term !== null) 70 | { 71 | return $this->term; 72 | } 73 | else 74 | { 75 | return null; 76 | } 77 | } 78 | 79 | public function get_scheme() 80 | { 81 | if ($this->scheme !== null) 82 | { 83 | return $this->scheme; 84 | } 85 | else 86 | { 87 | return null; 88 | } 89 | } 90 | 91 | public function get_label() 92 | { 93 | if ($this->label !== null) 94 | { 95 | return $this->label; 96 | } 97 | else 98 | { 99 | return $this->get_term(); 100 | } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Copyright.php: -------------------------------------------------------------------------------- 1 | url = $url; 56 | $this->label = $label; 57 | } 58 | 59 | public function __toString() 60 | { 61 | // There is no $this->data here 62 | return md5(serialize($this)); 63 | } 64 | 65 | public function get_url() 66 | { 67 | if ($this->url !== null) 68 | { 69 | return $this->url; 70 | } 71 | else 72 | { 73 | return null; 74 | } 75 | } 76 | 77 | public function get_attribution() 78 | { 79 | if ($this->label !== null) 80 | { 81 | return $this->label; 82 | } 83 | else 84 | { 85 | return null; 86 | } 87 | } 88 | } 89 | 90 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Credit.php: -------------------------------------------------------------------------------- 1 | role = $role; 57 | $this->scheme = $scheme; 58 | $this->name = $name; 59 | } 60 | 61 | public function __toString() 62 | { 63 | // There is no $this->data here 64 | return md5(serialize($this)); 65 | } 66 | 67 | public function get_role() 68 | { 69 | if ($this->role !== null) 70 | { 71 | return $this->role; 72 | } 73 | else 74 | { 75 | return null; 76 | } 77 | } 78 | 79 | public function get_scheme() 80 | { 81 | if ($this->scheme !== null) 82 | { 83 | return $this->scheme; 84 | } 85 | else 86 | { 87 | return null; 88 | } 89 | } 90 | 91 | public function get_name() 92 | { 93 | if ($this->name !== null) 94 | { 95 | return $this->name; 96 | } 97 | else 98 | { 99 | return null; 100 | } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Rating.php: -------------------------------------------------------------------------------- 1 | scheme = $scheme; 56 | $this->value = $value; 57 | } 58 | 59 | public function __toString() 60 | { 61 | // There is no $this->data here 62 | return md5(serialize($this)); 63 | } 64 | 65 | public function get_scheme() 66 | { 67 | if ($this->scheme !== null) 68 | { 69 | return $this->scheme; 70 | } 71 | else 72 | { 73 | return null; 74 | } 75 | } 76 | 77 | public function get_value() 78 | { 79 | if ($this->value !== null) 80 | { 81 | return $this->value; 82 | } 83 | else 84 | { 85 | return null; 86 | } 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePie/Restriction.php: -------------------------------------------------------------------------------- 1 | relationship = $relationship; 57 | $this->type = $type; 58 | $this->value = $value; 59 | } 60 | 61 | public function __toString() 62 | { 63 | // There is no $this->data here 64 | return md5(serialize($this)); 65 | } 66 | 67 | public function get_relationship() 68 | { 69 | if ($this->relationship !== null) 70 | { 71 | return $this->relationship; 72 | } 73 | else 74 | { 75 | return null; 76 | } 77 | } 78 | 79 | public function get_type() 80 | { 81 | if ($this->type !== null) 82 | { 83 | return $this->type; 84 | } 85 | else 86 | { 87 | return null; 88 | } 89 | } 90 | 91 | public function get_value() 92 | { 93 | if ($this->value !== null) 94 | { 95 | return $this->value; 96 | } 97 | else 98 | { 99 | return null; 100 | } 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /libraries/simplepie/SimplePieAutoloader.php: -------------------------------------------------------------------------------- 1 | path = dirname(__FILE__); 63 | } 64 | 65 | /** 66 | * Autoloader. 67 | * 68 | * @param string $class The name of the class to attempt to load. 69 | */ 70 | public function autoload($class) 71 | { 72 | // see if this request should be handled by this autoloader 73 | if (strpos($class, 'SimplePie') !== 0) { 74 | return; 75 | } 76 | 77 | $filename = $this->path . DIRECTORY_SEPARATOR . str_replace('_', DIRECTORY_SEPARATOR, $class) . '.php'; 78 | include $filename; 79 | } 80 | } -------------------------------------------------------------------------------- /site_config/README.txt: -------------------------------------------------------------------------------- 1 | Full-Text RSS Site Patterns 2 | --------------------------- 3 | 4 | Site patterns allow you to specify what should be extracted from specific sites. 5 | 6 | Please see http://help.fivefilters.org/customer/portal/articles/223153-site-patterns for more information. -------------------------------------------------------------------------------- /site_config/custom/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /site_config/description_filter_lib.php: -------------------------------------------------------------------------------- 1 | 0) { 5 | $str = mb_substr($str, 0, mb_strrpos($str, $postfix, "UTF-8"), "UTF-8"); 6 | } 7 | return $str; 8 | } 9 | 10 | function strip_prefix($str, $prefix) { 11 | if (mb_strpos($str, $prefix) > 0) { 12 | $str = mb_substr($str, 0, mb_strpos($str, $prefix, "UTF-8"), "UTF-8"); 13 | } 14 | return $str; 15 | } 16 | 17 | /** 18 | * 刪除字串的結尾到指定字串 19 | * strip_postfix_to("123-45", "-") -> 123 20 | * @param String $str 21 | * @param String $postfix_to 22 | * @return String 23 | */ 24 | function strip_postfix_to($str, $postfix_to) { 25 | $pos = strrpos($str, $postfix_to); 26 | if ($pos > 0) { 27 | $str = substr($str, 0, $pos); 28 | } 29 | return $str; 30 | } 31 | 32 | function strip_prefix_to($str, $to) { 33 | $pos = strpos($str, $to); 34 | if ($pos > 0) { 35 | $pos = $pos + strlen($to); 36 | $len = strlen($str); 37 | $str = substr($str, $pos, $len-$pos); 38 | } 39 | return $str; 40 | } 41 | 42 | function startsWith($haystack, $needle) 43 | { 44 | $length = strlen($needle); 45 | return (substr($haystack, 0, $length) === $needle); 46 | } 47 | 48 | function endsWith($haystack, $needle) 49 | { 50 | $length = strlen($needle); 51 | if ($length == 0) { 52 | return true; 53 | } 54 | 55 | return (substr($haystack, -$length) === $needle); 56 | } -------------------------------------------------------------------------------- /site_config/filter_skip_item.php: -------------------------------------------------------------------------------- 1 | get_title()) === "RSS feeds for Facebook pages and group" 6 | || trim($item->get_title()) === "Wallflux Atom Feed Demonstration" 7 | || trim($item->get_title()) === "") ) { 8 | return false; 9 | } 10 | else if (startsWith($_GET["url"], "https://www.wallflux.com/atom/") 11 | && strpos($item->get_title(), " - Wallflux Group info") > 0) { 12 | return false; 13 | } 14 | else if (startsWith($_GET["url"], "https://www.wallflux.com/feed/") 15 | && (strpos($item->get_title(), "Wallflux") > -1 || strpos($item->get_description(), "Wallflux") > -1) 16 | ) { 17 | return false; 18 | } 19 | else if (strpos($_GET["url"], "www.reddit.com") !== FALSE 20 | && strpos($_GET["url"], "googleplaydeals") !== FALSE ) { 21 | // Feed Title: Google Play Deals 22 | // ATOM URL: http://www.reddit.com/r/googleplaydeals/.rss 23 | // FTR URL: http://exp-full-text-rss-2013.dlll.nccu.edu.tw/full-text-rss/makefulltextfeed.php?url=exp-full-text-rss-2013.dlll.nccu.edu.tw%2Ffull-text-rss%2Fatom2rss%2Findex.php%3Fatom%3Dhttp%3A%2F%2Fwww.reddit.com%2Fr%2Fgoogleplaydeals%2F.rss&max=10&links=preserve&exc=&submit=Create+Feed 24 | 25 | // view-source:http://exp-full-text-rss-2013.dlll.nccu.edu.tw/full-text-rss/makefulltextfeed.php?url=exp-full-text-rss-2013.dlll.nccu.edu.tw%2Ffull-text-rss%2Fatom2rss%2Findex.php%3Fatom%3Dhttp%3A%2F%2Fwww.reddit.com%2Fr%2Fgoogleplaydeals%2F.rss&max=3&links=preserve&exc=&submit=Create+Feed 26 | if (strpos($item->get_title(), "[Meta] Removing the 1,000 downloads rule") !== FALSE) { 27 | return false; 28 | } 29 | //echo $item->get_title() ."|"; 30 | // meta_removing_the_1000_downloads_rule 31 | 32 | } 33 | 34 | return true; 35 | } -------------------------------------------------------------------------------- /site_config/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /site_config/permalink_blacklist.php: -------------------------------------------------------------------------------- 1 | 20170612 11 | * 資料庫 12 | */ 13 | "www.emeraldinsight.com", 14 | "www.reddit.com/r/googleplaydeals" 15 | ); 16 | 17 | // 不抽取黑名單的內容 18 | $is_in_blacklist = false; 19 | if (!url_allowed($permalink)) { 20 | $is_in_blacklist = true; 21 | } 22 | else { 23 | foreach ($permalink_blacklist AS $keyword) { 24 | if (strpos($permalink, $keyword) !== FALSE) { 25 | $is_in_blacklist = true; 26 | break; 27 | } 28 | } 29 | } 30 | 31 | //if ($is_in_blacklist === true) { 32 | // throw new Exception("In Black List"); 33 | //} 34 | 35 | return $is_in_blacklist; 36 | } -------------------------------------------------------------------------------- /site_config/standard/.wikipedia.org.txt: -------------------------------------------------------------------------------- 1 | title: //h1[@id='firstHeading'] 2 | body: //div[@id = 'bodyContent'] 3 | strip_id_or_class: editsection 4 | #strip_id_or_class: toc 5 | strip_id_or_class: vertical-navbox 6 | strip: //table[@id='toc'] 7 | strip: //div[@id='catlinks'] 8 | strip: //div[@id='jump-to-nav'] 9 | strip: //div[@class='thumbcaption']//div[@class='magnify'] 10 | strip: //table[@class='navbox'] 11 | strip: //table[contains(@class, 'infobox')] 12 | strip: //div[@class='dablink'] 13 | strip: //div[@id='contentSub'] 14 | strip: //table[contains(@class, 'metadata')] 15 | strip: //*[contains(@class, 'noprint')] 16 | strip: //span[@title='pronunciation:'] 17 | prune: no 18 | tidy: no 19 | test_url: http://en.wikipedia.org/wiki/Christopher_Lloyd -------------------------------------------------------------------------------- /site_config/standard/appguru.com.tw.txt: -------------------------------------------------------------------------------- 1 | body: //*[@id = 'content-text'] -------------------------------------------------------------------------------- /site_config/standard/bbs.onyx-international.com.cn.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'pct'][1] -------------------------------------------------------------------------------- /site_config/standard/boardgame-record.blogspot.tw.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; div[itemprop="blogPost"] -------------------------------------------------------------------------------- /site_config/standard/ccsx.tw.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'entry-content'] -------------------------------------------------------------------------------- /site_config/standard/chinese.engadget.com.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'postbody'] -------------------------------------------------------------------------------- /site_config/standard/data-sci.info.txt: -------------------------------------------------------------------------------- 1 | body: //article -------------------------------------------------------------------------------- /site_config/standard/easylife.tw.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; div.basement_content section -------------------------------------------------------------------------------- /site_config/standard/ez3c.tw.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; section -------------------------------------------------------------------------------- /site_config/standard/feed.ipc.me.txt: -------------------------------------------------------------------------------- 1 | body: //div[@id = 'post_content'] -------------------------------------------------------------------------------- /site_config/standard/feedproxy.google.com/~r/soft4funtw/.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; div.lucy-content -------------------------------------------------------------------------------- /site_config/standard/feeds.freegroup.org.txt: -------------------------------------------------------------------------------- 1 | body: //article[@class = 'type-post'] -------------------------------------------------------------------------------- /site_config/standard/freegroup.org.txt: -------------------------------------------------------------------------------- 1 | body: //article[@class = 'type-post'] -------------------------------------------------------------------------------- /site_config/standard/freewarehome.tw.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'entry-content'] -------------------------------------------------------------------------------- /site_config/standard/gnn.gamer.com.tw.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return str_replace(" data-src=", " src=", $c);}; div.GN-lbox3B -------------------------------------------------------------------------------- /site_config/standard/h9856.blogspot.com.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; div.post-body -------------------------------------------------------------------------------- /site_config/standard/h9856.blogspot.tw.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return $c;}; div.post-body -------------------------------------------------------------------------------- /site_config/standard/hkacger.com.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'post-content'] -------------------------------------------------------------------------------- /site_config/standard/incognitomail.com.txt: -------------------------------------------------------------------------------- 1 | body: //table[@class = 't12l_mail_details'] -------------------------------------------------------------------------------- /site_config/standard/index.php: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /site_config/standard/isvincent.pixnet.net.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'article-content-inner'] -------------------------------------------------------------------------------- /site_config/standard/libraryview.me.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'entry-content'] -------------------------------------------------------------------------------- /site_config/standard/linuxeden.com.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'content'] -------------------------------------------------------------------------------- /site_config/standard/mobileai.net.txt: -------------------------------------------------------------------------------- 1 | body: //[id = "main"] -------------------------------------------------------------------------------- /site_config/standard/mr6.cc.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'single-post-content'] -------------------------------------------------------------------------------- /site_config/standard/my.oschina.net.txt: -------------------------------------------------------------------------------- 1 | body: //div[@id = 'blogBody'] -------------------------------------------------------------------------------- /site_config/standard/netadmin.com.tw.txt: -------------------------------------------------------------------------------- 1 | body: //*[@id = 'post_con'] -------------------------------------------------------------------------------- /site_config/standard/news.xfastest.com.txt: -------------------------------------------------------------------------------- 1 | body: //div[@itemprop = 'articleBody']/*[not(div[@class = 'ssbp-container'])] -------------------------------------------------------------------------------- /site_config/standard/software.sopili.net.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {return str_replace('src="http://goo.gl/C1pBs" data-original=', " src=", $c);}; div.content -------------------------------------------------------------------------------- /site_config/standard/sub-fju-2017.blogspot.com.txt: -------------------------------------------------------------------------------- 1 | body: //div[@class = 'post-body'] -------------------------------------------------------------------------------- /site_config/standard/subscription-airiti-library.blogspot.tw.txt: -------------------------------------------------------------------------------- 1 | body: //div[@itemprop = 'blogPost'] -------------------------------------------------------------------------------- /site_config/standard/tw.battle.net.txt: -------------------------------------------------------------------------------- 1 | body: //*[@class = 'article-content'] 2 | -------------------------------------------------------------------------------- /site_config/standard/udn.com.txt: -------------------------------------------------------------------------------- 1 | body: phantomjs function ($c) {$start = strpos($c, "") + 26;$end = strpos($c, "", $start);$c = substr($c, $start, $end-$start);$c = str_replace('分享
', "", $c);return $c;}; * -------------------------------------------------------------------------------- /site_config/standard/version.php: -------------------------------------------------------------------------------- 1 |