All posts by cceye Liu

Android: make TextView looks exactly like EditText

android:background=”?attr/editTextBackground”

  <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Your text"
            android:hint="My hint"
            android:textColor="?attr/editTextColor"
            android:background="?attr/editTextBackground"
            android:gravity="center_vertical"
            android:textAppearance="?android:attr/textAppearanceMediumInverse"
            />

Math homework self service for kids, grade 3 review . 250 checks.

#!/usr/local/bin/perl

$totalcount=0;
$mistake=0;
$total=250;
while($totalcount<$total)
{
$no1=int(rand(time))%30;
$no2=int(rand(time))%30;

if($no1==0) 
{
$no1++;
}

if($no2==0) 
{
$no2++;
}
$plus=int(rand(time))%2;
$answer=0;
$wronglook=0;
GETINPUT:

if($plus==0)
{

$answer=$no1 + $no2;

print "$no1 + $no2 =";
if($no1>$no2)
{
$wronglook=$no1 - $no2;
}
else
{
$wronglook=$no2 - $no1;
}
}
else
{
$wronglook=$no1 + $no2;
if($no1>$no2)
{

print "$no1 - $no2 =";
$answer=$no1 - $no2;

}
else
{
print "$no2 - $no1 =";
$answer=$no2- $no1;
}
}



$userinput =  <STDIN>;
chomp($userinput);
if(length($userinput)==0)
{
print "Please input your answer\n";
goto GETINPUT;
}
$totalcount++;;

if($userinput == $answer) 
{
print "Great!!!! you did good job , the answer is Correct $userinput\n";
}
elsif($wronglook==$userinput)
{
print "Almost there!Let's take a second look at Operation sign is it + or -\n";
goto GETINPUT;

}
else
{
$mistake++;
print "wrong, the correct answer is ".$answer."\n";
}
if($totalcount%10==0)
{
$score=int(100-$mistake*100/$totalcount);
$left=$total-$totalcount;
$leftpercent=int($totalcount*100/400);
print "$totalcount problems done, ".$left." to go. finishing ".$leftpercent."\%. Score correct percentage rate ".$score."\%\n"; 
}

}

how to make wordpress widget plugin

How to make a wordpress adserv plugin

Today we will make a widget that can do

1. Rotation display ad tags , track impression, compare impression at even

In order to do this, we need an internal table , and setup this table during plugin setup.

In the wp-config.php file, a WordPress site owner can define a database table prefix. By default, the prefix is “wp_”, but you’ll need to check on the actual value and use it to define your database table name. This value is found in the $wpdb->prefix variable. (If you’re developing for a version of WordPress older than 2.0, you’ll need to use the $table_prefix global variable, which is deprecated in version 2.1).

So, if you want to create a table called (prefix)liveshoutbox, the first few lines of your table-creation function will be:

global $wpdb;

$table_name = $wpdb->prefix . “ad_rotation”;

Since we going to use this table later during query, it make sense to create a function that return this table name for later reuse.

function get_tablename () {
global $wpdb;

$table_name = $wpdb->prefix . “ad_rotation”;
}

CREATE TABLE IF NOT EXISTS $table_name (
`id` int(11) NOT NULL AUTO_INCREMENT,
`type` int(11) NOT NULL COMMENT ‘ 300 900 -1’,
`banner` text NOT NULL,
`impression` int(11) NOT NULL,
`current_period_minute` int(11) NOT NULL,
`totalimpression` int(11) NOT NULL,
`enabled` int(11) NOT NULL,
PRIMARY KEY (`id`),
KEY `id` (`id`),
KEY `type` (`type`),
KEY `id_2` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=latin1;

A Good document from WordPress main dev site is https://codex.wordpress.org/Creating_Tables_with_Plugins. now, we have got the table creation SQL, we need to find a way to exec this sql when plug-in been installed.

So we come to today’s first wordpress built in function,

Examples
If you have a function called myplugin_activate() in the main plugin file at either

wp-content/plugins/myplugin.php or
wp-content/plugins/myplugin/myplugin.php
use this code:

function myplugin_activate() {

// Activation code here…
}
register_activation_hook( __FILE__, ‘myplugin_activate’ );

This will call the myplugin_activate() function on activation of the plugin.

If your plugin uses the singleton class pattern, add the activation hook like so:

class MyPlugin {
static function install() {
// do not generate any output here
}
}

register_activation_hook( __FILE__, array( ‘ad_rotation’, ‘_install’ ) );

https://codex.wordpress.org/Function_Reference/register_activation_hook

register_deactivation_hook( __FILE__, array( ‘CMAdChanger’, ‘_uninstall’ ) );

So we have our first code ready to test out. and we got an error.

One thing worth to poitn out, testing wordpress plug-in has do be done at wordpress sites and watch error output at the web error log ,

eg /var/log/apache2/cceye.com_error.log

2016/10/12 14:40:21 [error] 3514#0: *42992556 FastCGI sent in stderr: “PHP Fatal error: Call to undefined function get_tablename() in adrotation.php on line 68” while reading response header from upstream, client: 108.161.162.92, server: cceye.com, request: “GET /wp-admin/plugins.php?action=deactivate&plugin=adrotation%2Fadrotation.php&plugin_status=all&paged=1&s&_wpnonce=21cdd674ab HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “www.cceye.com”

Ok, after fixing the the typo caused error, we move on next task: Show the form in backend to

1, allow add banner tag code in manage page
2, allow to show banner statics

let’s take a look of this https://codex.wordpress.org/Administration_Menus, ok, done. pretty long document. but here is the quick summary.

/** Step 2 (from text above). */
add_action( ‘admin_menu’, ‘my_plugin_menu’ );

/** Step 1. */
function my_plugin_menu() {
add_options_page( ‘Ad rotation Options’, ‘Ad Rotation’, ‘manage_options’, ‘my-unique-identifier’, ‘adrotation_options’ );
}

/** Step 3. */
function adrotation_options() {
if ( !current_user_can( ‘manage_options’ ) ) {
wp_die( __( ‘You do not have sufficient permissions to access this page.’ ) );
}
echo ‘

‘;
echo ‘

Here is where the form would go if I actually had options.

‘;
echo ‘

‘;
}

3, allow to select which type of tag to show in widget area.

Notice has right manage_options here is the list of all role and capabilite
https://codex.wordpress.org/Roles_and_Capabilities#update_core

Now I need to hold all the ad unit in memory so setting page can show it’s

ID,name,size,slot, TAG,IMPRESSION, 24 hours impression, total impression, enabled or not //size, slot

Now I have added admin menu, it’s time to insert data into the table we just created.

https://codex.wordpress.org/Class_Reference/wpdb

public function myAdminPage() {
// Echo the html here…
$adminpage=plugin_dir_path( __FILE__ ). ‘admin_ad.php’;

echo ‘This is the page contents ‘.$adminpage;

ob_start();
require_once $adminpage;
$content = ob_get_contents();
ob_end_clean();

echo $content;

}

prepare(

INSERT INTO $wpdb->postmeta
( post_id, meta_key, meta_value )
VALUES ( %d, %s, %s )
“,
10,
$metakey,
$metavalue
);
*/

#$tagcode = str_replace(“‘”, “\\'”, $_POST[‘bannercode’]);
#$name= str_replace(“‘”, “\\'”, $_POST[‘bannername’]);
/* $sqlquery=”INSERT INTO $tablename
(`id`, `name`, `size`, `type`, `banner`, `impression`, `current_period_minute`, `last_24h_impression`, `totalimpression`, `enabled`, `enabled_time`)
VALUES (NULL, %s ,%d ,%d,%s, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, CURRENT_TIMESTAMP)”;
*/
$sqlquery=”INSERT INTO $tablename (`id`, `name`, `size`, `type`, `banner`, `impression`, `current_period_minute`, `last_24h_impression`, `totalimpression`, `enabled`, `enabled_time`) VALUES (NULL, ‘”.$name.”‘,”.$size.”, “.$_POST[‘bannertype’].”,'”.$tagcode.”‘, ‘0’, ‘0’, ‘0’, ‘0’, ‘1’, CURRENT_TIMESTAMP)”;

#$sqlquery=$wpdb->prepare($sqlquery,$name,$_POST[‘bannertype’], $_POST[‘bannersize’],$tagcode);

$success=$wpdb->query($sqlquery);

#$success=$wpdb->query(“$sqlquery”);

if($success===false){
echo ‘Error saving banner’ ;
}
}

if (array_key_exists ( ‘update’, $_POST )) {
global $wpdb;

#$tagcode = str_replace(“‘”, “\\'”, $_POST[‘bannercode’]);
$sqlquery=”UPDATE “.$tablename.” SET `banner` = ‘”.$tagcode.”‘ , `enabled_time` = CURRENT_TIMESTAMP WHERE `wp_ad_rotation`.`id` =”. $_POST[‘id’].”;”;
$success=$wpdb->query(“$sqlquery”);

if($success===false){
echo ‘Error saving banner’ ;
}
}

if (array_key_exists ( ‘disable’, $_POST )) {
global $wpdb;

#$tagcode = str_replace(“‘”, “\\'”, $_POST[‘bannercode’]);
$sqlquery=”UPDATE “.$tablename.” SET `enabled` = 0 , `enabled_time` = CURRENT_TIMESTAMP WHERE `wp_ad_rotation`.`id` =”. $_POST[‘id’].”;”;
$success=$wpdb->query(“$sqlquery”);

if($success===false){
echo ‘Error saving banner’ ;
}
}

if (array_key_exists ( ‘enable’, $_POST )) {
global $wpdb;

#$tagcode = str_replace(“‘”, “\\'”, $_POST[‘bannercode’]);
$sqlquery=”UPDATE “.$tablename.” SET `enabled` = 1 , `enabled_time` = CURRENT_TIMESTAMP WHERE `wp_ad_rotation`.`id` =”. $_POST[‘id’].”;”;
$success=$wpdb->query(“$sqlquery”);

if($success===false){
echo ‘Error saving banner’ ;
}
}

if (array_key_exists ( ‘delete’, $_POST )) {
global $wpdb;

$sqlquery=”DELETE FROM “.$tablename.” WHERE `wp_ad_rotation`.`id` =”. $_POST[‘id’].”;”;
$success=$wpdb->query(“$sqlquery”);

if($success===false){
echo ‘Error saving banner’ ;
}
}

$banners=self::ad_get_banners();
$totalbanners=count($banners);
echo “total banners $totalbanners”;

?>

Add a banner tag here
ID:
Banner Name
Banner Type Web User interface
Popup

Banner size

330 square
728 leader board
automatic

Banner tag code

Now we have the admin menu ready. just need to start work on widget

form (insert/display meta)
update (save)
widget (display content to user UI)

NGINX WORDPRESS FASTCGI FAST CGI PUREGE

apt-get install build-essential libpcre3-dev libssl-dev zlib1g-dev
wget https://nginx.org/download/nginx-1.10.1.tar.gz
wget http://labs.frickle.com/files/ngx_cache_purge-2.3.tar.gz

sudo tar -xzf nginx-1.10.1.tar.gz
sudo tar -xzf ngx_cache_purge-2.3.tar.gz

sudo ./configure –sbin-path=/usr/sbin –conf-path=/etc/nginx/nginx.conf –error-log-path=/var/log/nginx/error.log –pid-path=/var/run/nginx.pid –lock-path=/var/lock/nginx.lock –http-log-path=/var/log/nginx/access.log –http-client-body-temp-path=/var/lib/nginx/body –http-proxy-temp-path=/var/lib/nginx/proxy –http-fastcgi-temp-path=/var/lib/nginx/fastcgi –with-debug –with-http_stub_status_module –with-http_flv_module –with-http_ssl_module –with-http_dav_module –with-ipv6 –add-module=/tmp/ngx_cache_purge-2.3
make && make install

mkdir -p /var/lib/nginx
mkdir -p /var/lib/nginx/body
mkdir -p /var/lib/nginx/fastcgi

nginx.conf

user www-data;
#GROUP www-data;
worker_processes 8;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid logs/nginx.pid;

events {
worker_connections 1024;
}

http {
include mime.types;
default_type application/octet-stream;

#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';

access_log /var/log/nginx/access.log;
error_log /var/log/nginx/error.log;

sendfile on;
#tcp_nopush on;

#keepalive_timeout 0;
keepalive_timeout 65;

gzip on;
gzip_http_version 1.1;
gzip_comp_level 2;
gzip_types text/plain text/html text/css
application/x-javascript text/xml
application/xml application/xml+rss
text/javascript;

upstream php {
#this should match value of "listen" directive in php-fpm pool
# server unix:/var/run/php5-fpm.sock;
server 127.0.0.1:9000;
}

proxy_cache_path /opt/nginx/cache/proxy levels=1:2 keys_zone=microcache:8m max_size=1000m inactive=600m;
proxy_temp_path /tmp/nginx;
proxy_cache_key "$scheme$request_method$host$request_uri";

#move next 3 lines to /etc/nginx/nginx.conf if you want to use fastcgi_cache across many sites
fastcgi_cache_path /opt/nginx/fastcgicache levels=1:2 keys_zone=WORDPRESS:500m inactive=60m;
fastcgi_cache_key "$scheme$request_method$host$request_uri";
fastcgi_cache_use_stale error timeout invalid_header http_500;

map $http_host $blogid {
default 0;

arcai.com 1;
www.arcai.com 1;

}

server{
listen 80 default_server;
server_name _; # This is just an invalid value which will never trigger on a real hostname.
access_log /var/log/nginx/default.access.log;
server_name_in_redirect off;

root /var/www/default/htdocs;
}
server {
listen 80;
server_name arcai.com www.arcai.com;

root /home/arcai/public/arcai.com/public/;
index index.php;

#fastcgi_cache start
set $no_cache 0;
set $loggable 1;
# POST requests and urls with a query string should always go to PHP
if ($request_method = POST) {
set $no_cache 1;
}
if ($query_string != "") {
set $no_cache 1;
}

# Don't cache uris containing the following segments
if ($request_uri ~ "(/wp-admin/|/xmlrpc.php|/wp-(app|cron|login|register|mail).php|paypal/|netCut/|wp-.*.php|/feed/|index.php|wp-comments-popup.php|wp-links-opml.php|wp-locations.php|sitemap(_index)?.xml|[a-z0-9_-]+-sitemap([0-9]+)?.xml)") {
set $no_cache 1;
}

# Don't use the cache for logged in users or recent commenters
if ($http_cookie ~* "comment_author|wordpress_[a-f0-9]+|wp-postpass|wordpress_no_cache|wordpress_logged_in") {
set $no_cache 1;
}

if ($request_uri ~ ^/(about-arcai-com|speed-test|netcut-defender-download|netCut/sharenetcut.html|netCut/sharenetcutdefender.html|netcut-defender|cut-off-action|root-android) )
{
set $no_cache 0;
}

if ($http_user_agent ~* "(Mediapartners-Google|wget)") {

set $no_cache 0;

}

location ~* \.(js|css|jpg|jpeg|gif|png|svg|ico)(\?.*)?$ {
expires 365d;
set $no_cache 0;
add_header Cache-Control "public";

}
location ~* \.(exe|apk)$ {
expires 1h;
add_header Cache-Control "public";
}

location ~ ^/netCut/(sharenetcut.html|netcutst.php|Update|Internet.php|billengine.php)
{
#set $host "api.example.com";
proxy_pass http://api.arcai.com:80;
proxy_set_header Host api.arcai.com;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

client_max_body_size 100M;
client_body_buffer_size 1m;
proxy_intercept_errors on;
proxy_buffering on;
proxy_buffer_size 128k;
proxy_buffers 256 16k;
proxy_busy_buffers_size 256k;
proxy_temp_file_write_size 256k;
proxy_max_temp_file_size 0;
proxy_read_timeout 300;
set $no_cache 0;
}

include global/restrictions.conf;

# Additional rules go here.

# Only include one of the files below.
include global/wordpress-ms-subdir.conf;

location ~ /purge(/.*) {
# Uncomment the following two lines to allow purge only from the webserver
#allow 127.0.0.1;
#deny all;

fastcgi_cache_purge WORDPRESS "$scheme$request_method$host$1";
}

# concurs with nginx's one
#
location ~ /\.ht {
deny all;
}
}

include /etc/nginx/sites-enabled/*;

access_log /var/log/nginx/arcai.com.access.log combined if=$no_cache;
error_log /var/log/nginx/arcai.com.error.log;

}

global/restrictions.conf

# Global restrictions configuration file.
# Designed to be included in any server {} block.
location = /favicon.ico {
log_not_found off;
access_log off;
}

location = /robots.txt {
allow all;
log_not_found off;
access_log off;
}

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~ /\. {
deny all;
}

# Deny access to any files with a .php extension in the uploads directory
# Works in sub-directory installs and also in multisite network
# Keep logging the requests to parse later (or to pass to firewall utilities such as fail2ban)
location ~* /(?:uploads|files)/.*\.php$ {
deny all;
}



global/wordpress-ms-subdir.conf

# WordPress multisite subdirectory rules.
# Designed to be included in any server {} block.

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
try_files $uri $uri/ /index.php?$args;
}

# Directives to send expires headers and turn off 404 error logging.
location ~* \.(js|css|png|jpg|jpeg|gif|ico)$ {
expires 24h;
log_not_found off;
}

location ~ ^/[_0-9a-zA-Z-]+/files/(.*)$ {
try_files /wp-content/blogs.dir/$blogid/files/$2 /wp-includes/ms-files.php?file=$2 ;
access_log off; log_not_found off; expires max;
}

#avoid php readfile()
location ^~ /blogs.dir {
internal;
alias /var/www/example.com/htdocs/wp-content/blogs.dir ;
access_log off; log_not_found off; expires max;
}

# Uncomment one of the lines below for the appropriate caching plugin (if used).
#include global/wordpress-ms-subdir-wp-super-cache.conf;
#include global/wordpress-ms-subdir-w3-total-cache.conf;

# Rewrite multisite '.../wp-.*' and '.../*.php'.
if (!-e $request_filename) {
rewrite /wp-admin$ $scheme://$host$uri/ permanent;
rewrite ^/[_0-9a-zA-Z-]+(/wp-.*) $1 last;
rewrite ^/[_0-9a-zA-Z-]+(/.*\.php)$ $1 last;
}

location ~ [^/]\.php(/|$) {
fastcgi_split_path_info ^(.+?\.php)(/.*)$;
if (!-f $document_root$fastcgi_script_name) {
return 404;
}
# This is a robust solution for path info security issue and works with "cgi.fix_pathinfo = 1" in /etc/php.ini (default)

include fastcgi.conf;
fastcgi_index index.php;
# fastcgi_intercept_errors on;
fastcgi_pass php;

fastcgi_cache WORDPRESS;
fastcgi_cache_valid 200 10m;

fastcgi_cache_bypass $no_cache;
fastcgi_no_cache $no_cache;

}

reference:

Put togther Nginx + ngx_cache_purge for WordPress on Ubuntu / CentOS


https://codex.wordpress.org/Nginx

Ubuntu find release name

lsb_release -a

 

lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux 7.9 (wheezy)
Release: 7.9
Codename: wheezy

 

lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.1 LTS
Release: 16.04
Codename: xenial

 

fail2ban new wordpress VPS setup must have

Install: apt-get install fail2ban

 

config:

/etc/fail2ban/jail.conf

SSHD and wordpress

[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
maxretry = 3
findtime = 3600
bantime = 7200

 

[wordpress]
enabled = true
filter = wordpress
logpath = /var/log/auth.log
port = http,https
maxretry = 10
findtime = 3600
bantime = 7200

TO USE WORDPRESS fail2ban,  also need to install wordpress plug-in “WP fail2ban

 

[http-get-dos]
enabled = true
port = http,https
filter = http-get-dos
logpath = /var/log/apache2/*access.log
# maxretry is how many GETs we can have in the findtime period before getting narky
maxretry = 400
# findtime is the time period in seconds in which we’re counting “retries” (300 seconds = 5 mins)
findtime = 60
# bantime is how long we should drop incoming GET requests for a given IP for, in this case it’s 5 minutes
bantime = 72000
action = iptables[name=HTTP, port=http, protocol=tcp]

 

/etc/fail2ban/filter.d/http-get-dos.conf
# Fail2Ban configuration file

[Definition]

# Option: failregex
# Note: This regex will match any GET entry in your logs, so basically all valid and not valid entries are a match.
# You should set up in the jail.conf file, the maxretry and findtime carefully in order to avoid false positives.

failregex = ^<HOST> -.*”(GET|POST).*

# Option: ignoreregex
# Notes.: regex to ignore. If this regex matches, the line is ignored.
# Values: TEXT
#
ignoreregex = (jpg|png) HTTP