update 2023-05-03 12:07:12
95
luci-app-koolproxyR/Makefile
Normal file
@ -0,0 +1,95 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-koolproxyR
|
||||
PKG_VERSION:=3.8.4
|
||||
PKG_RELEASE:=5
|
||||
|
||||
PKG_MAINTAINER:=panda-mute <wxuzju@gmail.com>
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
RSTRIP:=true
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luci-app-koolproxyR
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=LuCI support for koolproxyR
|
||||
DEPENDS:=+openssl-util +ipset +dnsmasq-full +@BUSYBOX_CONFIG_DIFF +iptables-mod-nat-extra +wget
|
||||
MAINTAINER:=panda-mute
|
||||
endef
|
||||
|
||||
define Package/luci-app-koolproxyR/description
|
||||
This package contains LuCI configuration pages for koolproxy.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-koolproxyR/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
( . /etc/uci-defaults/luci-koolproxy ) && rm -f /etc/uci-defaults/luci-koolproxy
|
||||
rm -f /tmp/luci-indexcache
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-koolproxyR/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/adblocklist
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/lib/upgrade/keep.d
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi/koolproxy
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/koolproxy
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_DIR) $(1)/usr/share/koolproxy
|
||||
$(INSTALL_DIR) $(1)/usr/share/koolproxy/data
|
||||
$(INSTALL_DIR) $(1)/usr/share/koolproxy/data/rules/
|
||||
|
||||
$(INSTALL_BIN) ./files/etc/uci-defaults/luci-koolproxy $(1)/etc/uci-defaults/luci-koolproxy
|
||||
$(INSTALL_BIN) ./files/etc/init.d/* $(1)/etc/init.d/
|
||||
$(INSTALL_DATA) ./files/etc/config/* $(1)/etc/config/
|
||||
$(INSTALL_DATA) ./files/etc/adblocklist/* $(1)/etc/adblocklist/
|
||||
$(INSTALL_DATA) ./files/lib/upgrade/keep.d/koolproxy $(1)/lib/upgrade/keep.d/
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/luci/model/cbi/koolproxy/global.lua $(1)/usr/lib/lua/luci/model/cbi/koolproxy/global.lua
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/luci/model/cbi/koolproxy/rss_rule.lua $(1)/usr/lib/lua/luci/model/cbi/koolproxy/rss_rule.lua
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/luci/controller/koolproxy.lua $(1)/usr/lib/lua/luci/controller/koolproxy.lua
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/luci/view/koolproxy/* $(1)/usr/lib/lua/luci/view/koolproxy/
|
||||
$(INSTALL_DATA) ./files/usr/lib/lua/luci/i18n/koolproxy.zh-cn.lmo $(1)/usr/lib/lua/luci/i18n/koolproxy.zh-cn.lmo
|
||||
$(INSTALL_BIN) ./files/usr/sbin/* $(1)/usr/sbin/
|
||||
$(INSTALL_BIN) ./files/usr/share/koolproxy/data/gen_ca.sh $(1)/usr/share/koolproxy/data/
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/data/openssl.cnf $(1)/usr/share/koolproxy/data/
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/data/user.txt $(1)/usr/share/koolproxy/data/
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/data/source.list $(1)/usr/share/koolproxy/data/
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/data/rules/* $(1)/usr/share/koolproxy/data/rules/
|
||||
$(INSTALL_BIN) ./files/usr/share/koolproxy/camanagement $(1)/usr/share/koolproxy/camanagement
|
||||
$(INSTALL_BIN) ./files/usr/share/koolproxy/kpupdate $(1)/usr/share/koolproxy/kpupdate
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/koolproxy_ipset.conf $(1)/usr/share/koolproxy/koolproxy_ipset.conf
|
||||
$(INSTALL_DATA) ./files/usr/share/koolproxy/dnsmasq.adblock $(1)/usr/share/koolproxy/dnsmasq.adblock
|
||||
ifeq ($(ARCH),mipsel)
|
||||
$(INSTALL_BIN) ./files/bin/mipsel $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),mips)
|
||||
$(INSTALL_BIN) ./files/bin/mips $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),i386)
|
||||
$(INSTALL_BIN) ./files/bin/i386 $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
$(INSTALL_BIN) ./files/bin/x86_64 $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),arm)
|
||||
$(INSTALL_BIN) ./files/bin/arm $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-koolproxyR))
|
33
luci-app-koolproxyR/README.md
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
修改了kpupdate,使其可以直接更新easylist、fanboy和yhost的规则。
|
||||
|
||||
## 准备工作:
|
||||
先运行:</br>
|
||||
`opkg install openssl-util ipset dnsmasq-full diffutils iptables-mod-nat-extra wget ca-bundle ca-certificates libustream-openssl`</br>
|
||||
手动安装以上依赖包</br>
|
||||
* 如果没有 **openssl** ,就不能正常生成证书,导致https过滤失败!
|
||||
* 如果没有 **ipset, dnsmasq-full, diffutils**,黑名单模式也会出现问题!(ipset 需要版本6),如果你的固件的busybox带有支持diff支持,那么diffutils包可以不安装
|
||||
* 如果没有 **iptables-mod-nat-extra** ,会导致mac过滤失效!
|
||||
* 如果没有 **wget, ca-bundle, ca-certificates, libustream-openssl** ,会导致规则文件更新失败,host规则条数变为0,如果你的固件的busybox带有支持https的wget,那么这几个包可以不安装
|
||||
|
||||
|
||||
|
||||
## 使用方法
|
||||
```Brach
|
||||
#源码根目录,进入package文件夹
|
||||
cd package
|
||||
#下载源码
|
||||
git clone https://github.com/jefferymvp/luci-app-koolproxyR
|
||||
#回到源码根目录
|
||||
cd ..
|
||||
make menuconfig
|
||||
#编译
|
||||
make package/luci-app-koolproxyR/{clean,compile} V=s
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
BIN
luci-app-koolproxyR/files/bin/arm
Executable file
BIN
luci-app-koolproxyR/files/bin/i386
Executable file
BIN
luci-app-koolproxyR/files/bin/mips
Executable file
BIN
luci-app-koolproxyR/files/bin/mipsel
Executable file
BIN
luci-app-koolproxyR/files/bin/x86_64
Executable file
0
luci-app-koolproxyR/files/etc/adblocklist/adblock
Normal file
1
luci-app-koolproxyR/files/etc/adblocklist/adblockip
Normal file
@ -0,0 +1 @@
|
||||
61.160.200.252
|
1
luci-app-koolproxyR/files/etc/adblocklist/adbypass
Normal file
@ -0,0 +1 @@
|
||||
v2ex.com
|
17
luci-app-koolproxyR/files/etc/config/koolproxy
Normal file
@ -0,0 +1,17 @@
|
||||
config global
|
||||
option time_update '4'
|
||||
option koolproxy_port '0'
|
||||
option startup_delay '5'
|
||||
option koolproxy_acl_default '0'
|
||||
option koolproxy_mode '2'
|
||||
option koolproxy_host '1'
|
||||
option koolproxy_rules 'fanboy.txt easylistchina.txt yhosts.txt kp.dat user.txt'
|
||||
option enabled '0'
|
||||
option koolproxy_ipv6 '0'
|
||||
|
||||
config rss_rule
|
||||
option load '1'
|
||||
option name 'kpr_our_rule.txt'
|
||||
option url 'https://github.com/user1121114685/koolproxyR_rule_list/raw/master/kpr_our_rule.txt'
|
||||
option file 'kpr_our_rule.txt'
|
||||
|
475
luci-app-koolproxyR/files/etc/init.d/koolproxy
Executable file
@ -0,0 +1,475 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#
|
||||
# Copyright (C) 2015 OpenWrt-dist
|
||||
# Copyright (C) 2016 fw867 <ffkykzs@gmail.com>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
CONFIG=koolproxy
|
||||
KP_DIR=/usr/share/koolproxy
|
||||
TMP_DIR=/tmp
|
||||
|
||||
alias echo_date='echo $(date +%Y年%m月%d日\ %X):'
|
||||
|
||||
config_n_get() {
|
||||
local ret=$(uci get $CONFIG.$1.$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
config_t_get() {
|
||||
local index=0
|
||||
[ -n "$4" ] && index=$4
|
||||
local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
add_ipset_conf() {
|
||||
if [ -s /etc/adblocklist/adbypass ]; then
|
||||
echo_date 添加白名单软连接...
|
||||
cat /etc/adblocklist/adbypass | sed "s/,/\n/g" | sed "s/^/ipset=&\/./g" | sed "s/$/\/white_kp_list/g" >> /tmp/adbypass.conf
|
||||
rm -rf /tmp/dnsmasq.d/adbypass.conf
|
||||
ln -sf /tmp/adbypass.conf /tmp/dnsmasq.d/adbypass.conf
|
||||
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
|
||||
if [ "$koolproxy_mode" == "2" ]; then
|
||||
if [ "$koolproxy_host" == "1" ];then
|
||||
echo_date 添加Adblock Plus Host软连接...
|
||||
ln -sf $KP_DIR/dnsmasq.adblock /tmp/dnsmasq.d/dnsmasq.adblock
|
||||
fi
|
||||
|
||||
echo_date 添加黑名单软连接...
|
||||
rm -rf /tmp/dnsmasq.d/koolproxy_ipset.conf
|
||||
ln -sf $KP_DIR/koolproxy_ipset.conf /tmp/dnsmasq.d/koolproxy_ipset.conf
|
||||
|
||||
echo_date 添加自定义黑名单软连接...
|
||||
if [ -s /etc/adblocklist/adblock ]; then
|
||||
cat /etc/adblocklist/adblock | sed "s/,/\n/g" | sed "s/^/ipset=&\/./g" | sed "s/$/\/black_koolproxy/g" >> /tmp/adblock.conf
|
||||
rm -rf /tmp/dnsmasq.d/adblock.conf
|
||||
ln -sf /tmp/adblock.conf /tmp/dnsmasq.d/adblock.conf
|
||||
fi
|
||||
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
}
|
||||
|
||||
remove_ipset_conf() {
|
||||
if [ -L "/tmp/dnsmasq.d/adbypass.conf" ]; then
|
||||
echo_date 移除白名单软连接...
|
||||
rm -rf /tmp/adbypass.conf
|
||||
rm -rf /tmp/dnsmasq.d/adbypass.conf
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
|
||||
if [ -L "/tmp/dnsmasq.d/koolproxy_ipset.conf" ]; then
|
||||
echo_date 移除黑名单软连接...
|
||||
rm -rf /tmp/dnsmasq.d/koolproxy_ipset.conf
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
|
||||
if [ -L "/tmp/dnsmasq.d/adblock.conf" ]; then
|
||||
echo_date 移除自定义黑名单软连接...
|
||||
rm -rf /tmp/dnsmasq.d/adblock.conf
|
||||
rm -rf /tmp/adblock.conf
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
|
||||
if [ -L "/tmp/dnsmasq.d/dnsmasq.adblock" ]; then
|
||||
echo_date 移除Adblock Plus Host软连接...
|
||||
rm -rf /tmp/dnsmasq.d/dnsmasq.adblock
|
||||
dnsmasq_restart=1
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
restart_dnsmasq() {
|
||||
if [ "$dnsmasq_restart" == "1" ]; then
|
||||
echo_date 重启dnsmasq进程...
|
||||
/etc/init.d/dnsmasq restart > /dev/null 2>&1
|
||||
fi
|
||||
}
|
||||
|
||||
creat_ipset() {
|
||||
echo_date 创建ipset名单
|
||||
# Load ipset netfilter kernel modules and kernel modules
|
||||
ipset -! create white_kp_list nethash
|
||||
ipset -! create black_koolproxy iphash
|
||||
cat $KP_DIR/data/rules/yhosts.txt $KP_DIR/data/rules/easylistchina.txt $KP_DIR/data/rules/fanboy.txt $KP_DIR/data/rules/user.txt | grep -Eo "(.\w+\:[1-9][0-9]{1,4})/" | grep -Eo "([0-9]{1,5})" | sort -un | sed -e '$a\80' -e '$a\443' | sed -e "s/^/-A kp_full_port &/g" -e "1 i\-N kp_full_port bitmap:port range 0-65535 " | ipset -R -!
|
||||
}
|
||||
|
||||
add_white_black_ip() {
|
||||
echo_date 添加ipset名单
|
||||
ip_lan="0.0.0.0/8 10.0.0.0/8 100.64.0.0/10 127.0.0.0/8 169.254.0.0/16 172.16.0.0/12 192.168.0.0/16 224.0.0.0/4 240.0.0.0/4"
|
||||
for ip in $ip_lan
|
||||
do
|
||||
ipset -A white_kp_list $ip >/dev/null 2>&1
|
||||
|
||||
done
|
||||
sed -e "s/^/add white_kp_list &/g" /etc/adblocklist/adbypassip | awk '{print $0} END{print "COMMIT"}' | ipset -R 2>/dev/null
|
||||
ipset -A black_koolproxy 110.110.110.110 >/dev/null 2>&1
|
||||
sed -e "s/^/add black_koolproxy &/g" /etc/adblocklist/adblockip | awk '{print $0} END{print "COMMIT"}' | ipset -R 2>/dev/null
|
||||
}
|
||||
|
||||
load_config() {
|
||||
ENABLED=$(config_t_get global enabled 0)
|
||||
[ $ENABLED -ne 1 ] && return 0
|
||||
koolproxy_mode=$(config_t_get global koolproxy_mode 1)
|
||||
koolproxy_host=$(config_t_get global koolproxy_host 0)
|
||||
koolproxy_acl_default=$(config_t_get global koolproxy_acl_default 1)
|
||||
koolproxy_port=$(config_t_get global koolproxy_port 0)
|
||||
koolproxy_bp_port=$(config_t_get global koolproxy_bp_port)
|
||||
koolproxy_ipv6=$(config_t_get global koolproxy_ipv6 0)
|
||||
config_load $CONFIG
|
||||
return 1
|
||||
}
|
||||
|
||||
__load_lan_acl() {
|
||||
local mac
|
||||
local ipaddr
|
||||
local proxy_mode
|
||||
config_get mac $1 mac
|
||||
config_get ipaddr $1 ipaddr
|
||||
config_get proxy_mode $1 proxy_mode
|
||||
[ -n "$ipaddr" ] && [ -z "$mac" ] && echo_date 加载ACL规则:【$ipaddr】模式为:$(get_mode_name $proxy_mode)
|
||||
[ -z "$ipaddr" ] && [ -n "$mac" ] && echo_date 加载ACL规则:【$mac】模式为:$(get_mode_name $proxy_mode)
|
||||
[ -n "$ipaddr" ] && [ -n "$mac" ] && echo_date 加载ACL规则:【$ipaddr】【$mac】模式为:$(get_mode_name $proxy_mode)
|
||||
#echo iptables -t nat -A KOOLPROXY $(factor $ipaddr "-s") $(factor $mac "-m mac --mac-source") -p tcp $(get_jump_mode $proxy_mode) $(get_action_chain $proxy_mode)
|
||||
iptables -t nat -A KOOLPROXY $(factor $ipaddr "-s") $(factor $mac "-m mac --mac-source") -p tcp $(get_jump_mode $proxy_mode) $(get_action_chain $proxy_mode)
|
||||
|
||||
acl_nu=`expr $acl_nu + 1`
|
||||
}
|
||||
|
||||
lan_acess_control() {
|
||||
acl_nu=0
|
||||
[ -z "$koolproxy_acl_default" ] && koolproxy_acl_default=1
|
||||
config_foreach __load_lan_acl acl_rule
|
||||
if [ $acl_nu -ne 0 ]; then
|
||||
echo_date 加载ACL规则:其余主机模式为:$(get_mode_name $koolproxy_acl_default)
|
||||
else
|
||||
echo_date 加载ACL规则:所有模式为:$(get_mode_name $koolproxy_acl_default)
|
||||
fi
|
||||
}
|
||||
|
||||
__load_exrule() {
|
||||
local file
|
||||
local exrule
|
||||
local enable
|
||||
config_get file $1 file
|
||||
config_get exrule $1 url
|
||||
config_get enable $1 load
|
||||
if [ -n "$exrule" ]; then
|
||||
if [ $enable -ne 1 ]; then
|
||||
[ -n "$file" ] && [ -f $KP_DIR/data/rules/$file ] && rm -f $KP_DIR/data/rules/$file
|
||||
uci set koolproxy.$1.time=""
|
||||
uci commit koolproxy
|
||||
return
|
||||
fi
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
file=$(echo $exrule |awk -F "/" '{print $NF}')
|
||||
uci set koolproxy.$1.file="$file"
|
||||
uci commit koolproxy
|
||||
fi
|
||||
|
||||
if [ ! -f $KP_DIR/data/rules/$file ]; then
|
||||
wget-ssl --quiet --timeout=5 --no-check-certificate $exrule -O $TMP_DIR/$file
|
||||
if [ "$?" == "0" ]; then
|
||||
uci set koolproxy.$1.time="`date +%Y-%m-%d" "%H:%M`"
|
||||
uci commit koolproxy
|
||||
mv $TMP_DIR/$file $KP_DIR/data/rules/$file
|
||||
else
|
||||
echo "koolproxy download rule $file failed!"
|
||||
[ -f $TMP_DIR/$file ] && rm -f $TMP_DIR/$file
|
||||
fi
|
||||
fi
|
||||
cat $KP_DIR/data/rules/$file >>$KP_DIR/data/rules/user.txt
|
||||
fi
|
||||
}
|
||||
|
||||
load_user_rules() {
|
||||
cp $KP_DIR/data/user.txt $KP_DIR/data/rules/user.txt
|
||||
config_foreach __load_exrule rss_rule
|
||||
}
|
||||
|
||||
load_rules() {
|
||||
sed -i '1,7s/1/0/g' $KP_DIR/data/source.list
|
||||
|
||||
local rulelist="$(uci -q get koolproxy.@global[0].koolproxy_rules)"
|
||||
for rule in $rulelist
|
||||
do
|
||||
case "$rule" in
|
||||
yhosts.txt)
|
||||
sed -i '1s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
kp.dat)
|
||||
sed -i '2s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
user.txt)
|
||||
sed -i '3s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
easylistchina.txt)
|
||||
sed -i '4s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
fanboy.txt)
|
||||
sed -i '5s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
local rulelist="$(uci -q get koolproxy.@global[0].thirdparty_rules)"
|
||||
for rule in $rulelist
|
||||
do
|
||||
case "$rule" in
|
||||
easylistchina.txt)
|
||||
sed -i '5s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
chengfeng.txt)
|
||||
sed -i '6s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
fanboy.txt)
|
||||
sed -i '7s/0/1/g' $KP_DIR/data/source.list
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
get_mode_name() {
|
||||
case "$1" in
|
||||
0)
|
||||
echo "不过滤"
|
||||
;;
|
||||
1)
|
||||
echo "http模式"
|
||||
;;
|
||||
2)
|
||||
echo "http + https"
|
||||
;;
|
||||
3)
|
||||
echo "full port"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_jump_mode() {
|
||||
case "$1" in
|
||||
0)
|
||||
echo "-j"
|
||||
;;
|
||||
*)
|
||||
echo "-g"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
get_action_chain() {
|
||||
case "$1" in
|
||||
0)
|
||||
echo "RETURN"
|
||||
;;
|
||||
1)
|
||||
echo "KP_HTTP"
|
||||
;;
|
||||
2)
|
||||
echo "KP_HTTPS"
|
||||
;;
|
||||
3)
|
||||
echo "KP_ALL_PORT"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
factor() {
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo ""
|
||||
else
|
||||
echo "$2 $1"
|
||||
fi
|
||||
}
|
||||
|
||||
load_nat() {
|
||||
echo_date 加载nat规则!
|
||||
#----------------------BASIC RULES---------------------
|
||||
echo_date 写入iptables规则到nat表中...
|
||||
# 创建KOOLPROXY nat rule
|
||||
iptables -t nat -N KOOLPROXY
|
||||
# 局域网地址不走KP
|
||||
iptables -t nat -A KOOLPROXY -m set --match-set white_kp_list dst -j RETURN
|
||||
# 生成对应CHAIN
|
||||
iptables -t nat -N KP_HTTP
|
||||
iptables -t nat -A KP_HTTP -p tcp -m multiport --dport 80 -j REDIRECT --to-ports 3000
|
||||
iptables -t nat -N KP_HTTPS
|
||||
iptables -t nat -A KP_HTTPS -p tcp -m multiport --dport 80,443 -j REDIRECT --to-ports 3000
|
||||
iptables -t nat -N KP_ALL_PORT
|
||||
#iptables -t nat -A KP_ALL_PORT -p tcp -j REDIRECT --to-ports 3000
|
||||
# 端口控制
|
||||
if [ "$koolproxy_port" == "1" ]; then
|
||||
echo_date 开启端口控制:【$koolproxy_bp_port】
|
||||
if [ -n "$koolproxy_bp_port" ]; then
|
||||
iptables -t nat -A KP_ALL_PORT -p tcp -m multiport ! --dport $koolproxy_bp_port -m set --match-set kp_full_port dst -j REDIRECT --to-ports 3000
|
||||
else
|
||||
iptables -t nat -A KP_ALL_PORT -p tcp -m set --match-set kp_full_port dst -j REDIRECT --to-ports 3000
|
||||
fi
|
||||
else
|
||||
iptables -t nat -A KP_ALL_PORT -p tcp -m set --match-set kp_full_port dst -j REDIRECT --to-ports 3000
|
||||
fi
|
||||
[ "$koolproxy_ipv6" == "1" ] && ip6tables -t nat -I PREROUTING -p tcp -j REDIRECT --to-ports 3000
|
||||
# 局域网控制
|
||||
lan_acess_control
|
||||
# 剩余流量转发到缺省规则定义的链中
|
||||
iptables -t nat -A KOOLPROXY -p tcp -j $(get_action_chain $koolproxy_acl_default)
|
||||
# 重定所有流量到 KOOLPROXY
|
||||
# 全局模式和视频模式
|
||||
[ "$koolproxy_mode" == "1" ] || [ "$koolproxy_mode" == "3" ] && iptables -t nat -I PREROUTING 1 -p tcp -j KOOLPROXY
|
||||
# ipset 黑名单模式
|
||||
[ "$koolproxy_mode" == "2" ] && iptables -t nat -I PREROUTING 1 -p tcp -m set --match-set black_koolproxy dst -j KOOLPROXY
|
||||
}
|
||||
|
||||
add_cru() {
|
||||
time=$(config_t_get global time_update)
|
||||
wirtecron=$(cat /etc/crontabs/root | grep "00 $time * * *" | grep kpupdate)
|
||||
if [ -z "$wirtecron" ];then
|
||||
sed -i '/kpupdate/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
echo "0 $time * * * /usr/share/koolproxy/kpupdate" >> /etc/crontabs/root
|
||||
fi
|
||||
}
|
||||
|
||||
del_cru() {
|
||||
sed -i '/kpupdate/d' /etc/crontabs/root >/dev/null 2>&1
|
||||
}
|
||||
|
||||
detect_cert(){
|
||||
if [ ! -f $KP_DIR/data/private/ca.key.pem -o ! -f $KP_DIR/data/cert/ca.crt ]; then
|
||||
echo_date 开始生成koolproxy证书,用于https过滤!
|
||||
cd $KP_DIR/data && sh gen_ca.sh
|
||||
fi
|
||||
}
|
||||
|
||||
flush_nat() {
|
||||
echo_date 移除nat规则...
|
||||
cd $TMP_DIR
|
||||
iptables -t nat -S | grep -E "KOOLPROXY|KP_HTTP|KP_HTTPS|KP_ALL_PORT" | sed 's/-A/iptables -t nat -D/g'|sed 1,4d > clean.sh && chmod 777 clean.sh && ./clean.sh
|
||||
[ -f $TMP_DIR/clean.sh ] && rm -f $TMP_DIR/clean.sh
|
||||
iptables -t nat -X KOOLPROXY > /dev/null 2>&1
|
||||
iptables -t nat -X KP_HTTP > /dev/null 2>&1
|
||||
iptables -t nat -X KP_HTTPS > /dev/null 2>&1
|
||||
iptables -t nat -X KP_ALL_PORT > /dev/null 2>&1
|
||||
ipset -F black_koolproxy > /dev/null 2>&1 && ipset -X black_koolproxy > /dev/null 2>&1
|
||||
ipset -F white_kp_list > /dev/null 2>&1 && ipset -X white_kp_list > /dev/null 2>&1
|
||||
ip6tables -t nat -D PREROUTING -p tcp -j REDIRECT --to-ports 3000 > /dev/null 2>&1
|
||||
}
|
||||
|
||||
export_ipt_rules() {
|
||||
FWI=$(uci get firewall.koolproxy.path 2>/dev/null)
|
||||
[ -n "$FWI" ] || return 0
|
||||
cat <<-CAT >>$FWI
|
||||
iptables-save -c | grep -v -E "KOOLPROXY|KP" | iptables-restore -c
|
||||
iptables-restore -n <<-EOF
|
||||
$(iptables-save | grep -E "KOOLPROXY|KP|^\*|^COMMIT" |\
|
||||
sed -e "s/^-A \(PREROUTING\)/-I \1 1/")
|
||||
EOF
|
||||
CAT
|
||||
return $?
|
||||
}
|
||||
|
||||
flush_ipt_rules() {
|
||||
FWI=$(uci get firewall.koolproxy.path 2>/dev/null)
|
||||
[ -n "$FWI" ] && echo '# firewall include file' >$FWI
|
||||
return 0
|
||||
}
|
||||
|
||||
pre_start() {
|
||||
load_config
|
||||
[ $? -ne 1 ] && return 0
|
||||
iptables -t nat -C PREROUTING -p tcp -j KOOLPROXY 2>/dev/null && [ $? -eq 0 ] && return 0;
|
||||
detect_cert
|
||||
load_rules
|
||||
load_user_rules
|
||||
add_ipset_conf && restart_dnsmasq
|
||||
creat_ipset
|
||||
add_white_black_ip
|
||||
load_nat
|
||||
flush_ipt_rules && export_ipt_rules
|
||||
add_cru
|
||||
[ "$koolproxy_mode" == "1" ] && echo_date 选择【全局过滤模式】
|
||||
[ "$koolproxy_mode" == "2" ] && echo_date 选择【IPSET过滤模式】
|
||||
if [ "$koolproxy_mode" == "3" ]; then
|
||||
echo_date 选择【视频过滤模式】
|
||||
sed -i '1s/1/0/g;2s/1/0/g' $KP_DIR/data/source.list
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
post_stop() {
|
||||
load_config
|
||||
[ $? -ne 1 ] && NO_RESTART_DNSMASQ=false
|
||||
if [ $NO_RESTART_DNSMASQ ]; then
|
||||
remove_ipset_conf
|
||||
else
|
||||
remove_ipset_conf && restart_dnsmasq
|
||||
fi
|
||||
flush_ipt_rules
|
||||
flush_nat
|
||||
del_cru
|
||||
return 0
|
||||
}
|
||||
|
||||
start_service() {
|
||||
echo_date ================== koolproxy启用 ================
|
||||
pre_start
|
||||
[ $? -ne 1 ] && return 0
|
||||
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/share/koolproxy/koolproxy
|
||||
procd_append_param command --mark
|
||||
procd_append_param command --ttl 160
|
||||
procd_append_param command --ipv6
|
||||
|
||||
procd_set_param respawn
|
||||
|
||||
procd_set_param file /etc/adblocklist/adblock
|
||||
procd_set_param file /etc/adblocklist/adblockip
|
||||
procd_set_param file /usr/share/koolproxy/data/user.txt
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
procd_close_instance
|
||||
|
||||
logger "koolproxy has started."
|
||||
echo_date =================================================
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
echo_date ====================== 关闭 =====================
|
||||
post_stop
|
||||
logger "koolproxy has stopped."
|
||||
echo_date =================================================
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
logger "koolproxy reload service."
|
||||
NO_RESTART_DNSMASQ=true
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "koolproxy"
|
||||
}
|
||||
|
||||
restart() {
|
||||
logger "koolproxy restart service."
|
||||
NO_RESTART_DNSMASQ=true
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
boot() {
|
||||
local delay=$(config_t_get global startup_delay 0)
|
||||
(sleep $delay && start >/dev/null 2>&1) &
|
||||
return 0
|
||||
}
|
17
luci-app-koolproxyR/files/etc/uci-defaults/luci-koolproxy
Executable file
@ -0,0 +1,17 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@koolproxy[-1]
|
||||
add ucitrack koolproxy
|
||||
set ucitrack.@koolproxy[-1].init=koolproxy
|
||||
commit ucitrack
|
||||
delete firewall.koolproxy
|
||||
set firewall.koolproxy=include
|
||||
set firewall.koolproxy.type=script
|
||||
set firewall.koolproxy.path=/var/etc/koolproxy.include
|
||||
set firewall.koolproxy.reload=1
|
||||
commit firewall
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
3
luci-app-koolproxyR/files/lib/upgrade/keep.d/koolproxy
Normal file
@ -0,0 +1,3 @@
|
||||
/usr/share/koolproxy/data/certs/ca.crt
|
||||
/usr/share/koolproxy/data/private/base.key.pem
|
||||
/usr/share/koolproxy/data/private/ca.key.pem
|
@ -0,0 +1,8 @@
|
||||
module("luci.controller.koolproxy",package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/koolproxy")then
|
||||
return
|
||||
end
|
||||
entry({"admin","services","koolproxy"},cbi("koolproxy/global"),_("KoolProxyR plus+"),1).dependent=true
|
||||
entry({"admin","services","koolproxy","rss_rule"},cbi("koolproxy/rss_rule"), nil).leaf=true
|
||||
end
|
@ -0,0 +1,392 @@
|
||||
-- Copyright 2018 Nick Peng (pymumu@gmail.com)
|
||||
|
||||
require ("nixio.fs")
|
||||
require ("luci.http")
|
||||
require ("luci.dispatcher")
|
||||
require ("nixio.fs")
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local http = require "luci.http"
|
||||
|
||||
|
||||
local o,t,e
|
||||
local v=luci.sys.exec("/usr/share/koolproxy/koolproxy -v")
|
||||
local s=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/easylistchina.txt | wc -l")
|
||||
local u=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/fanboy.txt | wc -l")
|
||||
local p=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/yhosts.txt | wc -l")
|
||||
local h=luci.sys.exec("grep -v '^!' /usr/share/koolproxy/data/rules/user.txt | wc -l")
|
||||
local i=luci.sys.exec("cat /usr/share/koolproxy/dnsmasq.adblock | wc -l")
|
||||
|
||||
if luci.sys.call("pidof koolproxy >/dev/null") == 0 then
|
||||
status = translate("<strong><font color=\"green\">KoolProxyR plus+ 运行中</font></strong>")
|
||||
else
|
||||
status = translate("<strong><font color=\"red\">KoolProxyR plus+ 已停止</font></strong>")
|
||||
end
|
||||
|
||||
o = Map("koolproxy", translate("KoolProxyR plus+ "), translate("KoolProxyR plus+是能识别adblock规则的免费开源软件,追求体验更快、更清洁的网络,屏蔽烦人的广告 <br /><font color=\"red\"><br /></font>"))
|
||||
|
||||
|
||||
t = o:section(TypedSection, "global")
|
||||
t.anonymous = true
|
||||
t.description = translate(string.format("%s<br /><br />", status))
|
||||
|
||||
t:tab("base",translate("Basic Settings"))
|
||||
|
||||
e = t:taboption("base", Flag, "enabled", translate("Enable"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
|
||||
e = t:taboption("base", DummyValue, "koolproxy_status", translate("程序版本"))
|
||||
e.value = string.format("[ %s ]", v)
|
||||
|
||||
e = t:taboption("base", Value, "startup_delay", translate("Startup Delay"))
|
||||
e:value(0, translate("Not enabled"))
|
||||
for _, v in ipairs({5, 10, 15, 25, 40}) do
|
||||
e:value(v, translate("%u seconds") %{v})
|
||||
end
|
||||
e.datatype = "uinteger"
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_mode", translate("Filter Mode"))
|
||||
e.default = 1
|
||||
e.rmempty = false
|
||||
e:value(1, translate("全局模式"))
|
||||
e:value(2, translate("IPSET模式"))
|
||||
e:value(3, translate("视频模式"))
|
||||
|
||||
e = t:taboption("base", MultiValue, "koolproxy_rules", translate("内置规则"))
|
||||
e.optional = false
|
||||
e.rmempty = false
|
||||
e:value("easylistchina.txt", translate("ABP规则"))
|
||||
e:value("fanboy.txt", translate("fanboy规则"))
|
||||
e:value("yhosts.txt", translate("yhosts规则"))
|
||||
e:value("kp.dat", translate("视频规则"))
|
||||
e:value("user.txt", translate("自定义规则"))
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_port", translate("端口控制"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e:value(0, translate("关闭"))
|
||||
e:value(1, translate("开启"))
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_ipv6", translate("IPv6支持"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e:value(0, translate("关闭"))
|
||||
e:value(1, translate("开启"))
|
||||
|
||||
e = t:taboption("base", Value, "koolproxy_bp_port", translate("例外端口"))
|
||||
e:depends("koolproxy_port", "1")
|
||||
e.rmempty = false
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>单端口:80 多端口:80,443</strong></font>"))
|
||||
|
||||
e=t:taboption("base",Flag,"koolproxy_host",translate("开启Adblock Plus Hosts"))
|
||||
e.default=0
|
||||
e:depends("koolproxy_mode","2")
|
||||
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_acl_default", translate("默认访问控制"))
|
||||
e.default = 1
|
||||
e.rmempty = false
|
||||
e:value(0, translate("不过滤"))
|
||||
e:value(1, translate("过滤HTTP协议"))
|
||||
e:value(2, translate("过滤HTTP(S)协议"))
|
||||
e:value(3, translate("全部过滤"))
|
||||
e.description = translate(string.format("<font color=\"blue\"><strong>访问控制设置中其他主机的默认规则</strong></font>"))
|
||||
|
||||
e = t:taboption("base", ListValue, "time_update", translate("定时更新"))
|
||||
for t = 0,23 do
|
||||
e:value(t,translate("每天"..t.."点"))
|
||||
end
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>定时更新订阅规则与Adblock Plus Hosts</strong></font>"))
|
||||
|
||||
e = t:taboption("base", Button, "restart", translate("规则状态"))
|
||||
e.inputtitle = translate("更新规则")
|
||||
e.inputstyle = "reload"
|
||||
e.write = function()
|
||||
luci.sys.call("/usr/share/koolproxy/kpupdate 2>&1 >/dev/null")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","koolproxy"))
|
||||
end
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>更新订阅规则与Adblock Plus Hosts</strong></font><br /><font color=\"green\">ABP规则: %s条<br />fanboy规则: %s条<br />yhosts规则: %s条<br />自定义规则: %s条<br />Host: %s条</font><br />", s, u, p, h, i))
|
||||
t:tab("cert",translate("Certificate Management"))
|
||||
|
||||
e=t:taboption("cert",DummyValue,"c1status",translate("<div align=\"left\">Certificate Restore</div>"))
|
||||
e=t:taboption("cert",FileUpload,"")
|
||||
e.template="koolproxy/caupload"
|
||||
e=t:taboption("cert",DummyValue,"",nil)
|
||||
e.template="koolproxy/cadvalue"
|
||||
if nixio.fs.access("/usr/share/koolproxy/data/certs/ca.crt")then
|
||||
e=t:taboption("cert",DummyValue,"c2status",translate("<div align=\"left\">Certificate Backup</div>"))
|
||||
e=t:taboption("cert",Button,"certificate")
|
||||
e.inputtitle=translate("Backup Download")
|
||||
e.inputstyle="reload"
|
||||
e.write=function()
|
||||
luci.sys.call("/usr/share/koolproxy/camanagement backup 2>&1 >/dev/null")
|
||||
Download()
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","koolproxy"))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
t:tab("white_weblist",translate("网站白名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adbypass"
|
||||
e = t:taboption("white_weblist", TextValue, "adbypass_domain")
|
||||
e.description = translate("这些已经加入的网站将不会使用过滤器。请输入网站的域名,每行只能输入一个网站域名。例如google.com。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adbypass", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adbypass /etc/adblocklist/adbypass") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adbypass")
|
||||
end
|
||||
|
||||
t:tab("weblist",translate("Set Backlist Of Websites"))
|
||||
|
||||
local i = "/etc/adblocklist/adblock"
|
||||
e = t:taboption("weblist", TextValue, "adblock_domain")
|
||||
e.description = translate("加入的网址将走广告过滤端口。只针对黑名单模式。只能输入WEB地址,如:google.com,每个地址一行。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adblock", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adblock /etc/adblocklist/adblock") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adblock")
|
||||
end
|
||||
|
||||
t:tab("white_iplist",translate("IP白名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adbypassip"
|
||||
e = t:taboption("white_iplist", TextValue, "adbypass_ip")
|
||||
e.description = translate("这些已加入的ip地址将使用代理,但只有GFW型号。请输入ip地址或ip地址段,每行只能输入一个ip地址。例如,112.123.134.145 / 24或112.123.134.145。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adbypassip", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adbypassip /etc/adblocklist/adbypassip") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adbypassip")
|
||||
end
|
||||
|
||||
t:tab("iplist",translate("IP黑名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adblockip"
|
||||
e = t:taboption("iplist", TextValue, "adblock_ip")
|
||||
e.description = translate("这些已经加入的ip地址不会使用filter.Please输入ip地址或ip地址段,每行只能输入一个ip地址。例如,112.123.134.145 / 24或112.123.134.145。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adblockip", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adblockip /etc/adblocklist/adblockip") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adblockip")
|
||||
end
|
||||
|
||||
t:tab("customlist", translate("Set Backlist Of custom"))
|
||||
|
||||
local i = "/usr/share/koolproxy/data/user.txt"
|
||||
e = t:taboption("customlist", TextValue, "user_rule")
|
||||
e.description = translate("Enter your custom rules, each row.")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/user.txt", value)
|
||||
if (luci.sys.call("cmp -s /tmp/user.txt /usr/share/koolproxy/data/user.txt") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/user.txt")
|
||||
end
|
||||
|
||||
t:tab("logs",translate("View the logs"))
|
||||
|
||||
local i = "/var/log/koolproxy.log"
|
||||
e = t:taboption("logs", TextValue, "kpupdate_log")
|
||||
e.description = translate("Koolproxy Logs")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
end
|
||||
|
||||
t=o:section(TypedSection,"acl_rule",translate("KoolProxyR 访问控制"),
|
||||
translate("ACLs is a tools which used to designate specific IP filter mode,The MAC addresses added to the list will be filtered using https"))
|
||||
t.template="cbi/tblsection"
|
||||
t.sortable=true
|
||||
t.anonymous=true
|
||||
t.addremove=true
|
||||
e=t:option(Value,"remarks",translate("Client Remarks"))
|
||||
e.width="30%"
|
||||
e.rmempty=true
|
||||
e=t:option(Value,"ipaddr",translate("IP Address"))
|
||||
e.width="20%"
|
||||
e.datatype="ip4addr"
|
||||
luci.ip.neighbors({family = 4}, function(neighbor)
|
||||
if neighbor.reachable then
|
||||
e:value(neighbor.dest:string(), "%s (%s)" %{neighbor.dest:string(), neighbor.mac})
|
||||
end
|
||||
end)
|
||||
e=t:option(Value,"mac",translate("MAC Address"))
|
||||
e.width="20%"
|
||||
e.rmempty=true
|
||||
e.datatype="macaddr"
|
||||
luci.ip.neighbors({family = 4}, function(neighbor)
|
||||
if neighbor.reachable then
|
||||
e:value(neighbor.mac, "%s (%s)" %{neighbor.mac, neighbor.dest:string()})
|
||||
end
|
||||
end)
|
||||
e=t:option(ListValue,"proxy_mode",translate("访问控制"))
|
||||
e.width="20%"
|
||||
e.default=1
|
||||
e.rmempty=false
|
||||
e:value(0,translate("不过滤"))
|
||||
e:value(1,translate("http only"))
|
||||
e:value(2,translate("http + https"))
|
||||
e:value(3,translate("full port"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
t=o:section(TypedSection,"rss_rule",translate("KoolProxyR 规则订阅"), translate("请确保订阅规则的兼容性"))
|
||||
t.anonymous=true
|
||||
t.addremove=true
|
||||
t.sortable=true
|
||||
t.template="cbi/tblsection"
|
||||
t.extedit=luci.dispatcher.build_url("admin/services/koolproxy/rss_rule/%s")
|
||||
|
||||
t.create=function(...)
|
||||
local sid=TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(t.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
e=t:option(Flag,"load",translate("启用"))
|
||||
e.default=0
|
||||
e.rmempty=false
|
||||
|
||||
e=t:option(DummyValue,"name",translate("规则名称"))
|
||||
function e.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
e=t:option(DummyValue,"url",translate("规则地址"))
|
||||
function e.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
e=t:option(DummyValue,"time",translate("更新时间"))
|
||||
|
||||
function Download()
|
||||
local t,e
|
||||
t=nixio.open("/tmp/upload/koolproxyca.tar.gz","r")
|
||||
luci.http.header('Content-Disposition','attachment; filename="koolproxyCA.tar.gz"')
|
||||
luci.http.prepare_content("application/octet-stream")
|
||||
while true do
|
||||
e=t:read(nixio.const.buffersize)
|
||||
if(not e)or(#e==0)then
|
||||
break
|
||||
else
|
||||
luci.http.write(e)
|
||||
end
|
||||
end
|
||||
t:close()
|
||||
luci.http.close()
|
||||
end
|
||||
local t,e
|
||||
t="/tmp/upload/"
|
||||
nixio.fs.mkdir(t)
|
||||
luci.http.setfilehandler(
|
||||
function(o,a,i)
|
||||
if not e then
|
||||
if not o then return end
|
||||
e=nixio.open(t..o.file,"w")
|
||||
if not e then
|
||||
return
|
||||
end
|
||||
end
|
||||
if a and e then
|
||||
e:write(a)
|
||||
end
|
||||
if i and e then
|
||||
e:close()
|
||||
e=nil
|
||||
luci.sys.call("/usr/share/koolproxy/camanagement restore 2>&1 >/dev/null")
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
|
||||
|
||||
return o
|
@ -0,0 +1,36 @@
|
||||
local m, s, o
|
||||
local koolproxy = "koolproxy"
|
||||
local sid = arg[1]
|
||||
|
||||
m = Map(koolproxy, "%s - %s" %{translate("koolproxy"), translate("编辑规则")})
|
||||
m.redirect = luci.dispatcher.build_url("admin/services/koolproxy")
|
||||
|
||||
if not arg[1] or m.uci:get(koolproxy, sid) ~= "rss_rule" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
-- [[ Edit Rule ]]--
|
||||
s = m:section(NamedSection, sid, "rss_rule")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
|
||||
o=s:option(Flag,"load",translate("启用"))
|
||||
o.default=0
|
||||
o.rmempty=false
|
||||
|
||||
o=s:option(Value,"name",translate("规则描述"))
|
||||
o.rmempty=true
|
||||
|
||||
o=s:option(Value,"url",translate("规则地址"))
|
||||
o.rmempty=false
|
||||
o.placeholder="[https|http|ftp]://[Hostname]/[File]"
|
||||
function o.validate(self, value)
|
||||
if not value then
|
||||
return nil
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
@ -0,0 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span style="color: green">
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
write(pcdata(val))
|
||||
%>
|
||||
</span>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value" style="display:inline-block; width: 400px" for="ulfile"><font color="red"><%:Upload backup file,The file name must be koolproxyCA.tar.gz%></font></label><br />
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
|
||||
<input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload Restore%>" />
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,3 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="koolproxy_status"><%=pcdata(self:cfgvalue(section) or self.default or "")%></span>
|
||||
<%+cbi/valuefooter%>
|
@ -0,0 +1,16 @@
|
||||
<%#
|
||||
Copyright 2016 Chen RuiWei <crwbak@gmail.com>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
<% include("cbi/map") %>
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(2, '<%=luci.dispatcher.build_url("admin", "services", "koolproxy", "status")%>', null,
|
||||
function(x, result)
|
||||
{
|
||||
var status = document.getElementsByClassName('koolproxy_status');
|
||||
status[0].innerHTML = result.koolproxy?'<b><font color=green><%=translate("RUNNING")%></font></b>':'<b><font color=red><%=translate("NOT RUNNING")%></font></b>';
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
23
luci-app-koolproxyR/files/usr/sbin/adblockplus
Executable file
@ -0,0 +1,23 @@
|
||||
#!/bin/sh
|
||||
echo "$(date "+%F %T"): 正在下载adblockplus规则..."
|
||||
wget-ssl --quiet --no-check-certificate https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt -O /tmp/adlist.txt
|
||||
if [ "$?" == "0" ]; then
|
||||
grep ^\|\|[^\*]*\^$ /tmp/adlist.txt | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > /tmp/dnsmasq.adblock
|
||||
rm -f /tmp/adlist.txt
|
||||
diff /tmp/dnsmasq.adblock /usr/share/koolproxy/dnsmasq.adblock >/dev/null
|
||||
[ $? = 0 ] && echo "$(date "+%F %T"): adblockplus本地规则和服务器规则相同,无需更新!" && rm -f /tmp/dnsmasq.adblock && return 1
|
||||
echo "$(date "+%F %T"): 检测到adblockplus规则有更新,开始转换规则!"
|
||||
sed -i '/youku/d' /tmp/dnsmasq.adblock >/dev/null 2>&1
|
||||
sed -i '/[1-9]\{1,3\}\.[1-9]\{1,3\}\.[1-9]\{1,3\}\.[1-9]\{1,3\}/d' /tmp/dnsmasq.adblock >/dev/null 2>&1
|
||||
mv /tmp/dnsmasq.adblock /usr/share/koolproxy/dnsmasq.adblock
|
||||
echo "$(date "+%F %T"): adblockplus规则转换完成,应用新规则。"
|
||||
echo ""
|
||||
echo "$(date "+%F %T"): 重启dnsmasq进程"
|
||||
/etc/init.d/dnsmasq restart > /dev/null 2>&1
|
||||
|
||||
return 0
|
||||
else
|
||||
echo "$(date "+%F %T"): 获取在线版本时出现错误! "
|
||||
[ -f /tmp/adlist.txt ] && rm -f /tmp/adlist.txt
|
||||
return 1
|
||||
fi
|
66
luci-app-koolproxyR/files/usr/share/koolproxy/camanagement
Executable file
@ -0,0 +1,66 @@
|
||||
#!/bin/sh
|
||||
kpfolder="/usr/share/koolproxy/data"
|
||||
kplogfile="/var/log/koolproxy.log"
|
||||
readyfolder="/tmp/upload/koolproxy"
|
||||
|
||||
backup() {
|
||||
if [ ! -f $kpfolder/private/ca.key.pem ]; then
|
||||
echo "未找到ca.key.pem,请先运行Koolproxy一次!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f $kpfolder/private/base.key.pem ]; then
|
||||
echo "未找到base.key.pem,请先运行Koolproxy一次!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f $kpfolder/certs/ca.crt ]; then
|
||||
echo "未找到ca.crt,请先运行Koolproxy一次!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -p /tmp/upload
|
||||
cd $kpfolder
|
||||
tar czf /tmp/upload/koolproxyca.tar.gz private/ca.key.pem private/base.key.pem certs/ca.crt
|
||||
[ -f /tmp/upload/koolproxyca.tar.gz ] && echo "证书备份已成功生成。" > $kplogfile
|
||||
}
|
||||
|
||||
restore() {
|
||||
if [ ! -f /tmp/upload/koolproxyCA.tar.gz ]; then
|
||||
echo "未找到备份文件,文件名必须为koolproxyCA.tar.gz或已损坏,请检查备份文件!" >> $kplogfile
|
||||
else
|
||||
mkdir -p $readyfolder
|
||||
cd $readyfolder
|
||||
tar xzf /tmp/upload/koolproxyCA.tar.gz
|
||||
fi
|
||||
if [ ! -f $readyfolder/private/ca.key.pem ]; then
|
||||
echo "未找到ca.key.pem,备份文件不正确或已损坏,请检查备份文件!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f $readyfolder/private/base.key.pem ]; then
|
||||
echo "未找到base.key.pem,备份文件不正确或已损坏,请检查备份文件!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
if [ ! -f $readyfolder/certs/ca.crt ]; then
|
||||
echo "未找到ca.crt,备份文件不正确或已损坏,请检查备份文件!" > $kplogfile
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mv -f $readyfolder/private/ca.key.pem $kpfolder/private/ca.key.pem
|
||||
mv -f $readyfolder/private/base.key.pem $kpfolder/private/base.key.pem
|
||||
mv -f $readyfolder/certs/ca.crt $kpfolder/certs/ca.crt
|
||||
rm -rf $readyfolder
|
||||
rm -f /tmp/upload/koolproxyCA.tar.gz
|
||||
echo "证书成功还原,重启Koolproxy。" > $kplogfile
|
||||
/etc/init.d/koolproxy restart
|
||||
}
|
||||
|
||||
case "$*" in
|
||||
"backup")
|
||||
backup
|
||||
;;
|
||||
"restore")
|
||||
restore
|
||||
;;
|
||||
"help")
|
||||
echo "use backup or restore"
|
||||
;;
|
||||
esac
|
29
luci-app-koolproxyR/files/usr/share/koolproxy/data/gen_ca.sh
Executable file
@ -0,0 +1,29 @@
|
||||
#!/bin/sh
|
||||
alias echo_date='echo $(date +%Y年%m月%d日\ %X):'
|
||||
|
||||
if [ ! -f openssl.cnf ]; then
|
||||
echo_date "Cannot found openssl.cnf"
|
||||
exit 1
|
||||
fi
|
||||
if [ -f /usr/share/koolproxy/data/private/ca.key.pem ]; then
|
||||
echo_date "已经有证书了!"
|
||||
else
|
||||
echo_date "生成证书中..."
|
||||
|
||||
#step 1, root ca
|
||||
mkdir -p certs private
|
||||
rm -f serial private/ca.key.pem
|
||||
chmod 700 private
|
||||
echo 1000 > serial
|
||||
openssl genrsa -aes256 -passout pass:koolshare -out private/ca.key.pem 2048
|
||||
chmod 400 private/ca.key.pem
|
||||
openssl req -config openssl.cnf -passin pass:koolshare \
|
||||
-subj "/C=CN/ST=Beijing/L=KP/O=KoolProxy inc/CN=koolproxy.com" \
|
||||
-key private/ca.key.pem \
|
||||
-new -x509 -days 7300 -sha256 -extensions v3_ca \
|
||||
-out certs/ca.crt
|
||||
|
||||
#step 2, domain rsa key
|
||||
openssl genrsa -aes256 -passout pass:koolshare -out private/base.key.pem 2048
|
||||
echo_date "证书生成完毕..."
|
||||
fi
|
132
luci-app-koolproxyR/files/usr/share/koolproxy/data/openssl.cnf
Executable file
@ -0,0 +1,132 @@
|
||||
# OpenSSL root CA configuration file.
|
||||
# Copy to `/root/ca/openssl.cnf`.
|
||||
|
||||
[ ca ]
|
||||
# `man ca`
|
||||
default_ca = CA_default
|
||||
|
||||
[ CA_default ]
|
||||
# Directory and file locations.
|
||||
dir = ./ca
|
||||
certs = $dir/certs
|
||||
crl_dir = $dir/crl
|
||||
new_certs_dir = $dir/newcerts
|
||||
database = $dir/index.txt
|
||||
serial = $dir/serial
|
||||
RANDFILE = $dir/private/.rand
|
||||
|
||||
# The root key and root certificate.
|
||||
private_key = $dir/private/ca.key.pem
|
||||
certificate = $dir/certs/ca.cert.pem
|
||||
|
||||
# For certificate revocation lists.
|
||||
crlnumber = $dir/crlnumber
|
||||
crl = $dir/crl/ca.crl.pem
|
||||
crl_extensions = crl_ext
|
||||
default_crl_days = 30
|
||||
|
||||
# SHA-1 is deprecated, so use SHA-2 instead.
|
||||
default_md = sha256
|
||||
|
||||
name_opt = ca_default
|
||||
cert_opt = ca_default
|
||||
default_days = 375
|
||||
preserve = no
|
||||
policy = policy_strict
|
||||
|
||||
[ policy_strict ]
|
||||
# The root CA should only sign intermediate certificates that match.
|
||||
# See the POLICY FORMAT section of `man ca`.
|
||||
countryName = match
|
||||
stateOrProvinceName = match
|
||||
organizationName = match
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ policy_loose ]
|
||||
# Allow the intermediate CA to sign a more diverse range of certificates.
|
||||
# See the POLICY FORMAT section of the `ca` man page.
|
||||
countryName = optional
|
||||
stateOrProvinceName = optional
|
||||
localityName = optional
|
||||
organizationName = optional
|
||||
organizationalUnitName = optional
|
||||
commonName = supplied
|
||||
emailAddress = optional
|
||||
|
||||
[ req ]
|
||||
# Options for the `req` tool (`man req`).
|
||||
default_bits = 2048
|
||||
distinguished_name = req_distinguished_name
|
||||
string_mask = utf8only
|
||||
|
||||
# SHA-1 is deprecated, so use SHA-2 instead.
|
||||
default_md = sha256
|
||||
|
||||
# Extension to add when the -x509 option is used.
|
||||
x509_extensions = v3_ca
|
||||
|
||||
[ req_distinguished_name ]
|
||||
# See <https://en.wikipedia.org/wiki/Certificate_signing_request>.
|
||||
countryName = Country Name (2 letter code)
|
||||
stateOrProvinceName = State or Province Name
|
||||
localityName = Locality Name
|
||||
0.organizationName = Organization Name
|
||||
organizationalUnitName = Organizational Unit Name
|
||||
commonName = Common Name
|
||||
emailAddress = Email Address
|
||||
|
||||
# Optionally, specify some defaults.
|
||||
countryName_default = GB
|
||||
stateOrProvinceName_default = England
|
||||
localityName_default =
|
||||
0.organizationName_default = Alice Ltd
|
||||
organizationalUnitName_default =
|
||||
emailAddress_default =
|
||||
|
||||
[ v3_ca ]
|
||||
# Extensions for a typical CA (`man x509v3_config`).
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
basicConstraints = critical, CA:true
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
|
||||
[ v3_intermediate_ca ]
|
||||
# Extensions for a typical intermediate CA (`man x509v3_config`).
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid:always,issuer
|
||||
basicConstraints = critical, CA:true, pathlen:0
|
||||
keyUsage = critical, digitalSignature, cRLSign, keyCertSign
|
||||
|
||||
[ usr_cert ]
|
||||
# Extensions for client certificates (`man x509v3_config`).
|
||||
basicConstraints = CA:FALSE
|
||||
nsCertType = client, email
|
||||
nsComment = "OpenSSL Generated Client Certificate"
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer
|
||||
keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = clientAuth, emailProtection
|
||||
|
||||
[ server_cert ]
|
||||
# Extensions for server certificates (`man x509v3_config`).
|
||||
basicConstraints = CA:FALSE
|
||||
nsCertType = server
|
||||
nsComment = "OpenSSL Generated Server Certificate"
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer:always
|
||||
keyUsage = critical, digitalSignature, keyEncipherment
|
||||
extendedKeyUsage = serverAuth
|
||||
|
||||
[ crl_ext ]
|
||||
# Extension for CRLs (`man x509v3_config`).
|
||||
authorityKeyIdentifier=keyid:always
|
||||
|
||||
[ ocsp ]
|
||||
# Extension for OCSP signing certificates (`man ocsp`).
|
||||
basicConstraints = CA:FALSE
|
||||
subjectKeyIdentifier = hash
|
||||
authorityKeyIdentifier = keyid,issuer
|
||||
keyUsage = critical, digitalSignature
|
||||
extendedKeyUsage = critical, OCSPSigning
|
21958
luci-app-koolproxyR/files/usr/share/koolproxy/data/rules/fanboy.txt
Normal file
BIN
luci-app-koolproxyR/files/usr/share/koolproxy/data/rules/kp.dat
Normal file
@ -0,0 +1,49 @@
|
||||
! ******************************* koolproxyR 自定义过滤语法简表 *******************************
|
||||
! ------------------------ 规则基于adblock规则,并进行了语法部分的扩展 ------------------------
|
||||
! ABP规则请参考https://adblockplus.org/zh_CN/filters,下面为大致摘要
|
||||
! "!" 为行注释符,注释行以该符号起始作为一行注释语义,用于规则描述
|
||||
! "@@" 为白名单符,白名单具有最高优先级,放行过滤的网站,例如:@@||taobao.com
|
||||
! "@@@@" 超级白名单,比白名单符拥有更高的优先级,主要用于放行https网站,例如:@@@@||https://taobao.com
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! "*" 为字符通配符,能够匹配0长度或任意长度的字符串,该通配符不能与正则语法混用。
|
||||
! "^" 为分隔符,可以是除了字母、数字或者 _ - . % 之外的任何字符。
|
||||
! "~" 为排除标识符,通配符能过滤大多数广告,但同时存在误杀, 可以通过排除标识符修正误杀链接。
|
||||
! 注:通配符仅在 url 规则中支持,html 规则中不支持
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! "|" 为管线符号,来表示地址的最前端或最末端
|
||||
! "||" 为子域通配符,方便匹配主域名下的所有子域
|
||||
! 用法及例子如下:(以下等号表示等价于)
|
||||
! ||xx.com/ad = http://xx.com/ad* || http://*.xx.com/ad*
|
||||
! ||http://xx.com/ad = http://xx.com/ad* || http://*.xx.com/ad*
|
||||
! ||https://xx.com/ad = https://xx.com/ad* || https://*.xx.com/ad*
|
||||
! |xx.com/ad = http://xx.com/ad*
|
||||
! |http://xx.com/ad = http://xx.com/ad*
|
||||
! |https://xx.com/ad = https://xx.com/ad*
|
||||
! ad = http://*ad*
|
||||
! http://ad = http://*ad*
|
||||
! https://ad = 不支持,需要指定域名,如下例
|
||||
! https://xx.com/ad = |https://xx.com/ad = https://xx.com/ad*
|
||||
! [同时可以表示两个以及两个以上的域名]如下例子
|
||||
! https://xx.ad.com 和 https://xxx.xx.ad.com = ||https://ad.com (注意! 由于https的原因使用要非常谨慎,不可以大范围使用)
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 兼容adblock规则的html规则语法,例如:
|
||||
! fulldls.com,torrentzap.com##.tp_reccomend_banner
|
||||
! 但是推荐写成以下标准写法:
|
||||
! ||fulldls.com##.tp_reccomend_banner
|
||||
! ||torrentzap.com##.tp_reccomend_banner
|
||||
! 如果一个网站html规则有多条,可以合并为这样:
|
||||
! ||torrentzap.com##.tp_reccomend_banner,.ad_top,[class="ad_right"]......
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 文本替换语法:$s@匹配内容@替换内容@
|
||||
! 非标准端口过滤语法:||abc.com:8081/ad.html或者|http://adb.com:8081/
|
||||
! 文本替换例子:|http://cdn.pcbeta.js.inimc.com/data/cache/common.js?$s@old@new@
|
||||
! 重定向语法:$r@匹配内容@替换内容@
|
||||
! 重定向例子:|http://koolshare.cn$r@http://koolshare.cn/*@http://www.qq.com@
|
||||
! 注:文本替换语法及重定向语法中的匹配内容不仅支持通配符功能,而且额外支持以下功能
|
||||
! 支持通配符 * 和 ? 表示单个字符
|
||||
! 支持全正则匹配,/正则内容/ 表示应用正则匹配
|
||||
! 正则替换:替换内容支持 $1 $2 这样的符号
|
||||
! 普通替换:替换内容支持 * 这样的符号,表示把命中的内容复制到替换的内容。(类似 $1 $2,但是 * 号会自动计算数字)
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 未来将逐步添加相关语法,兼容adblock puls的更多语法,敬请期待。
|
||||
! ******************************************************************************************
|
16687
luci-app-koolproxyR/files/usr/share/koolproxy/data/rules/yhosts.txt
Normal file
@ -0,0 +1,5 @@
|
||||
0|yhosts.txt||yhosts规则
|
||||
0|kp.dat||视频规则
|
||||
0|user.txt||自定义规则
|
||||
0|easylistchina.txt||ABP规则
|
||||
0|fanboy.txt||Fanboy规则
|
49
luci-app-koolproxyR/files/usr/share/koolproxy/data/user.txt
Normal file
@ -0,0 +1,49 @@
|
||||
! ******************************* koolproxyR 自定义过滤语法简表 *******************************
|
||||
! ------------------------ 规则基于adblock规则,并进行了语法部分的扩展 ------------------------
|
||||
! ABP规则请参考https://adblockplus.org/zh_CN/filters,下面为大致摘要
|
||||
! "!" 为行注释符,注释行以该符号起始作为一行注释语义,用于规则描述
|
||||
! "@@" 为白名单符,白名单具有最高优先级,放行过滤的网站,例如:@@||taobao.com
|
||||
! "@@@@" 超级白名单,比白名单符拥有更高的优先级,主要用于放行https网站,例如:@@@@||https://taobao.com
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! "*" 为字符通配符,能够匹配0长度或任意长度的字符串,该通配符不能与正则语法混用。
|
||||
! "^" 为分隔符,可以是除了字母、数字或者 _ - . % 之外的任何字符。
|
||||
! "~" 为排除标识符,通配符能过滤大多数广告,但同时存在误杀, 可以通过排除标识符修正误杀链接。
|
||||
! 注:通配符仅在 url 规则中支持,html 规则中不支持
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! "|" 为管线符号,来表示地址的最前端或最末端
|
||||
! "||" 为子域通配符,方便匹配主域名下的所有子域
|
||||
! 用法及例子如下:(以下等号表示等价于)
|
||||
! ||xx.com/ad = http://xx.com/ad* || http://*.xx.com/ad*
|
||||
! ||http://xx.com/ad = http://xx.com/ad* || http://*.xx.com/ad*
|
||||
! ||https://xx.com/ad = https://xx.com/ad* || https://*.xx.com/ad*
|
||||
! |xx.com/ad = http://xx.com/ad*
|
||||
! |http://xx.com/ad = http://xx.com/ad*
|
||||
! |https://xx.com/ad = https://xx.com/ad*
|
||||
! ad = http://*ad*
|
||||
! http://ad = http://*ad*
|
||||
! https://ad = 不支持,需要指定域名,如下例
|
||||
! https://xx.com/ad = |https://xx.com/ad = https://xx.com/ad*
|
||||
! [同时可以表示两个以及两个以上的域名]如下例子
|
||||
! https://xx.ad.com 和 https://xxx.xx.ad.com = ||https://ad.com (注意! 由于https的原因使用要非常谨慎,不可以大范围使用)
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 兼容adblock规则的html规则语法,例如:
|
||||
! fulldls.com,torrentzap.com##.tp_reccomend_banner
|
||||
! 但是推荐写成以下标准写法:
|
||||
! ||fulldls.com##.tp_reccomend_banner
|
||||
! ||torrentzap.com##.tp_reccomend_banner
|
||||
! 如果一个网站html规则有多条,可以合并为这样:
|
||||
! ||torrentzap.com##.tp_reccomend_banner,.ad_top,[class="ad_right"]......
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 文本替换语法:$s@匹配内容@替换内容@
|
||||
! 非标准端口过滤语法:||abc.com:8081/ad.html或者|http://adb.com:8081/
|
||||
! 文本替换例子:|http://cdn.pcbeta.js.inimc.com/data/cache/common.js?$s@old@new@
|
||||
! 重定向语法:$r@匹配内容@替换内容@
|
||||
! 重定向例子:|http://koolshare.cn$r@http://koolshare.cn/*@http://www.qq.com@
|
||||
! 注:文本替换语法及重定向语法中的匹配内容不仅支持通配符功能,而且额外支持以下功能
|
||||
! 支持通配符 * 和 ? 表示单个字符
|
||||
! 支持全正则匹配,/正则内容/ 表示应用正则匹配
|
||||
! 正则替换:替换内容支持 $1 $2 这样的符号
|
||||
! 普通替换:替换内容支持 * 这样的符号,表示把命中的内容复制到替换的内容。(类似 $1 $2,但是 * 号会自动计算数字)
|
||||
! ------------------------------------------------------------------------------------------
|
||||
! 未来将逐步添加相关语法,兼容adblock puls的更多语法,敬请期待。
|
||||
! ******************************************************************************************
|
5102
luci-app-koolproxyR/files/usr/share/koolproxy/dnsmasq.adblock
Normal file
6584
luci-app-koolproxyR/files/usr/share/koolproxy/koolproxy_ipset.conf
Normal file
602
luci-app-koolproxyR/files/usr/share/koolproxy/kpupdate
Executable file
@ -0,0 +1,602 @@
|
||||
#!/bin/sh
|
||||
# set -x
|
||||
|
||||
. /lib/functions.sh
|
||||
|
||||
CONFIG=koolproxy
|
||||
KP_DIR=/usr/share/koolproxy
|
||||
TMP_DIR=/tmp/koolproxy
|
||||
LOGFILE="/var/log/koolproxy.log"
|
||||
KSROOT=/usr/share
|
||||
#source $KSROOT/scripts/base.sh
|
||||
#eval `dbus export koolproxyR_`
|
||||
alias echo_date='echo $(date +%Y年%m月%d日\ %X):'
|
||||
|
||||
url_cjx="https://shaoxia1991.coding.net/p/cjxlist/d/cjxlist/git/raw/master/cjx-annoyance.txt"
|
||||
url_kp="https://raw.githubusercontent.com/houzi-/CDN/master/kp.dat"
|
||||
url_kp_md5="https://raw.githubusercontent.com/houzi-/CDN/master/kp.dat.md5"
|
||||
url_easylist="https://easylist-downloads.adblockplus.org/easylistchina.txt"
|
||||
url_yhosts="https://shaoxia1991.coding.net/p/yhosts/d/yhosts/git/raw/master/hosts"
|
||||
url_yhosts1="https://shaoxia1991.coding.net/p/yhosts/d/yhosts/git/raw/master/data/tvbox.txt"
|
||||
kpr_our_rule="https://shaoxia1991.coding.net/p/koolproxyR_rule_list/d/koolproxyR_rule_list/git/raw/master/kpr_our_rule.txt"
|
||||
url_fanboy="https://secure.fanboy.co.nz/fanboy-annoyance.txt"
|
||||
|
||||
#在订阅中的用户地址改为,这个地址速度更快:https://dev.tencent.com/u/shaoxia1991/p/koolproxyR_rule_list/git/raw/master/kpr_our_rule.txt
|
||||
|
||||
config_t_get() {
|
||||
local index=0
|
||||
[ -n "$4" ] && index=$4
|
||||
local ret=$(uci get $CONFIG.@$1[$index].$2 2>/dev/null)
|
||||
echo ${ret:=$3}
|
||||
}
|
||||
|
||||
limit_log() {
|
||||
local log=$1
|
||||
[ ! -f "$log" ] && return
|
||||
local sc=100
|
||||
[ -n "$2" ] && sc=$2
|
||||
local count=$(grep -c "" $log)
|
||||
if [ $count -gt $sc ];then
|
||||
let count=count-$sc
|
||||
sed -i "1,$count d" $log
|
||||
fi
|
||||
}
|
||||
|
||||
init_env() {
|
||||
rm -rf "$TMP_DIR"
|
||||
mkdir -p "$TMP_DIR"
|
||||
}
|
||||
|
||||
restart_koolproxy() {
|
||||
/etc/init.d/koolproxy restart
|
||||
}
|
||||
|
||||
__compare_file() {
|
||||
local descript=$1
|
||||
local localPath=$2
|
||||
local remoteUrl=$3
|
||||
|
||||
echo $(date "+%F %T"): ------------------- $descript更新 ------------------- >>$LOGFILE
|
||||
local filename=`basename $localPath`
|
||||
local remotePath="$TMP_DIR/$filename"
|
||||
wget-ssl -qT5 --no-check-certificate "$remoteUrl" -O "$remotePath"
|
||||
if [ "$?" == "0" ]; then
|
||||
if [ -f "$localPath" ]; then
|
||||
localMD5=`md5sum "$localPath" | awk '{print $1}'`
|
||||
localNum=`cat "$localPath" | grep -v '^!' | wc -l`
|
||||
else
|
||||
localMD5="文件不存在"
|
||||
localNum="0"
|
||||
fi
|
||||
remoteMD5=`md5sum "$remotePath" | awk '{print $1}'`
|
||||
remoteNum=`cat "$remotePath" | grep -v '^!' | wc -l`
|
||||
|
||||
echo $(date "+%F %T"): 本地版本MD5:$localMD5 >>$LOGFILE
|
||||
echo $(date "+%F %T"): 本地版本条数:$localNum >>$LOGFILE
|
||||
|
||||
echo $(date "+%F %T"): 在线版本MD5:$remoteMD5 >>$LOGFILE
|
||||
echo $(date "+%F %T"): 在线版本条数:$remoteNum >>$LOGFILE
|
||||
|
||||
|
||||
if [ "$localMD5" != "$remoteMD5" ];then
|
||||
echo $(date "+%F %T"): 检测到更新,开始更新规则! >>$LOGFILE
|
||||
mv -f "$remotePath" "$localPath"
|
||||
echo $(date "+%F %T"): 更新成功! >>$LOGFILE
|
||||
|
||||
return 0
|
||||
fi
|
||||
else
|
||||
echo "$(date "+%F %T"): 获取在线版本时出现错误! " >>$LOGFILE
|
||||
|
||||
fi
|
||||
return 1
|
||||
}
|
||||
|
||||
__update_rule() {
|
||||
local name
|
||||
local file
|
||||
local exrule
|
||||
local enable
|
||||
config_get name $1 name
|
||||
config_get file $1 file
|
||||
config_get exrule $1 url
|
||||
config_get enable $1 load
|
||||
if [ -n "$file" ] && [ -n "$exrule" ]; then
|
||||
if [ $enable -ne 1 ]; then
|
||||
return
|
||||
fi
|
||||
__compare_file "$name" "$KP_DIR/data/rules/$file" "$exrule"
|
||||
if [ "$?" == "0" ]; then
|
||||
uci set koolproxy.$1.time="`date +%Y-%m-%d" "%H:%M`"
|
||||
uci commit koolproxy
|
||||
RESTART_KOOLPROXY=true
|
||||
fi
|
||||
cat $KP_DIR/data/rules/$file >>$KP_DIR/data/rules/user.txt
|
||||
|
||||
fi
|
||||
}
|
||||
|
||||
kpr_update_rules() {
|
||||
echo $(date "+%F %T"): ------------------- 内置规则更新 ------------------- >>$LOGFILE
|
||||
echo_date =======================================================================================================
|
||||
echo_date 开始更新koolproxyR的规则,请等待...
|
||||
# 赋予文件夹权限
|
||||
chmod -R 777 $KSROOT/koolproxy/data/rules
|
||||
# update 中国简易列表 2.0
|
||||
if [[ "1" == "1" ]]; then
|
||||
echo_date " ---------------------------------------------------------------------------------------"
|
||||
# wget --no-check-certificate --timeout=8 -qO - $url_easylist > /tmp/easylistchina.txt
|
||||
for i in {1..5}; do
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/easylistchina.txt $url_easylist
|
||||
easylistchina_rule_nu_local=`grep -E -v "^!" /tmp/easylistchina.txt | wc -l`
|
||||
if [[ "$easylistchina_rule_nu_local" -gt 5000 ]]; then
|
||||
break
|
||||
else
|
||||
echo_date easylistchina规则文件下载失败
|
||||
koolproxyR_basic_easylist_failed=1
|
||||
fi
|
||||
done
|
||||
for i in {1..5}; do
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/cjx-annoyance.txt $url_cjx
|
||||
cjx_rule_nu_local=`grep -E -v "^!" /tmp/cjx-annoyance.txt | wc -l`
|
||||
if [[ "$cjx_rule_nu_local" -gt 500 ]]; then
|
||||
break
|
||||
else
|
||||
echo_date cjx-annoyance规则文件下载失败
|
||||
koolproxyR_basic_easylist_failed=1
|
||||
fi
|
||||
done
|
||||
#for i in {1..5}; do
|
||||
# wget -4 -a /tmp/upload/kpr_log.txt -O $KSROOT/koolproxy/data/rules/kpr_our_rule.txt $kpr_our_rule
|
||||
# kpr_our_rule_nu_local=`grep -E -v "^!" $KSROOT/koolproxy/data/rules/kpr_our_rule.txt | wc -l`
|
||||
# if [[ "$kpr_our_rule_nu_local" -gt 500 ]]; then
|
||||
# break
|
||||
# else
|
||||
# echo_date kpr_our_rule规则文件下载失败
|
||||
# koolproxyR_basic_easylist_failed=1
|
||||
# fi
|
||||
#done
|
||||
|
||||
# expr 进行运算,将统计到的规则条数相加 如果条数大于 10000 条就说明下载完毕
|
||||
#easylistchina_rule_local=`expr $kpr_our_rule_nu_local + $cjx_rule_nu_local + $easylistchina_rule_nu_local`
|
||||
easylistchina_rule_local=`expr $cjx_rule_nu_local + $easylistchina_rule_nu_local`
|
||||
cat /tmp/cjx-annoyance.txt >> /tmp/easylistchina.txt
|
||||
rm /tmp/cjx-annoyance.txt
|
||||
easylist_rules_local=`cat $KSROOT/koolproxy/data/rules/easylistchina.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
easylist_rules_local1=`cat /tmp/easylistchina.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
|
||||
echo_date KPR主规则的本地版本号: $easylist_rules_local
|
||||
echo_date KPR主规则的在线版本号: $easylist_rules_local1
|
||||
if [[ "$koolproxyR_basic_easylist_failed" != "1" ]]; then
|
||||
if [[ "$easylistchina_rule_local" -gt 10000 ]]; then
|
||||
if [[ "$easylist_rules_local" != "$easylist_rules_local1" ]]; then
|
||||
echo_date 检测到 KPR主规则 已更新,现在开始更新...
|
||||
echo_date 将临时的KPR主规则文件移动到指定位置
|
||||
mv /tmp/easylistchina.txt $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
koolproxyR_https_ChinaList=1
|
||||
else
|
||||
echo_date 检测到 KPR主规则本地版本号和在线版本号相同,那还更新个毛啊!
|
||||
fi
|
||||
fi
|
||||
else
|
||||
echo_date KPR主规则文件下载失败!
|
||||
fi
|
||||
else
|
||||
echo_date 未打开 KPR主规则 的更新开关!
|
||||
fi
|
||||
|
||||
# update 补充规则
|
||||
if [[ "1" == "1" ]]; then
|
||||
echo_date " ---------------------------------------------------------------------------------------"
|
||||
for i in {1..5}; do
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/yhosts.txt $url_yhosts
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/tvbox.txt $url_yhosts1
|
||||
cat /tmp/tvbox.txt >> /tmp/yhosts.txt
|
||||
replenish_rules_local=`cat $KSROOT/koolproxy/data/rules/yhosts.txt | sed -n '2p' | cut -d "=" -f2`
|
||||
replenish_rules_local1=`cat /tmp/yhosts.txt | sed -n '2p' | cut -d "=" -f2`
|
||||
mobile_nu_local=`grep -E -v "^!" /tmp/yhosts.txt | wc -l`
|
||||
echo_date 补充规则本地版本号: $replenish_rules_local
|
||||
echo_date 补充规则在线版本号: $replenish_rules_local1
|
||||
if [[ "$mobile_nu_local" -gt 5000 ]]; then
|
||||
if [[ "$replenish_rules_local" != "$replenish_rules_local1" ]]; then
|
||||
echo_date 将临时文件覆盖到原始 补充规则 文件
|
||||
mv /tmp/yhosts.txt $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
koolproxyR_https_mobile=1
|
||||
break
|
||||
else
|
||||
echo_date 检测到 补充规则 本地版本号和在线版本号相同,那还更新个毛啊!
|
||||
fi
|
||||
else
|
||||
echo_date 补充规则文件下载失败!
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo_date 未打开 补充规则 的更新开关!
|
||||
fi
|
||||
|
||||
# update 视频规则
|
||||
if [[ "1" == "1" ]] || [[ -n "$1" ]]; then
|
||||
echo_date " ---------------------------------------------------------------------------------------"
|
||||
for i in {1..5}; do
|
||||
kpr_video_md5=`md5sum $KSROOT/koolproxy/data/rules/kp.dat | awk '{print $1}'`
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/kp.dat.md5 $url_kp_md5
|
||||
kpr_video_new_md5=`cat /tmp/kp.dat.md5 | sed -n '1p'`
|
||||
echo_date 远程视频规则md5:$kpr_video_new_md5
|
||||
echo_date 您本地视频规则md5:$kpr_video_md5
|
||||
|
||||
if [[ "$kpr_video_md5" != "$kpr_video_new_md5" ]]; then
|
||||
echo_date 检测到新版视频规则.开始更新..........
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/kp.dat $url_kp
|
||||
kpr_video_download_md5=`md5sum /tmp/kp.dat | awk '{print $1}'`
|
||||
echo_date 您下载的视频规则md5:$kpr_video_download_md5
|
||||
if [[ "$kpr_video_download_md5" == "$kpr_video_new_md5" ]]; then
|
||||
echo_date 将临时文件覆盖到原始 视频规则 文件
|
||||
mv /tmp/kp.dat $KSROOT/koolproxy/data/rules/kp.dat
|
||||
mv /tmp/kp.dat.md5 $KSROOT/koolproxy/data/rules/kp.dat.md5
|
||||
break
|
||||
else
|
||||
echo_date 视频规则md5校验不通过...
|
||||
fi
|
||||
else
|
||||
echo_date 检测到 视频规则 本地版本号和在线版本号相同,那还更新个毛啊!
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo_date 未打开 视频规则 的更新开关!
|
||||
fi
|
||||
|
||||
# update fanboy规则
|
||||
if [[ "1" == "1" ]]; then
|
||||
echo_date " ---------------------------------------------------------------------------------------"
|
||||
for i in {1..5}; do
|
||||
wget -4 -a /tmp/upload/kpr_log.txt -O /tmp/fanboy-annoyance.txt $url_fanboy
|
||||
# wget --no-check-certificate --timeout=8 -qO - $url_fanboy > /tmp/fanboy-annoyance.txt
|
||||
# 检测是否开启fanboy 全规则版本
|
||||
if [[ "$koolproxyR_fanboy_all_rules" == "1" ]]; then
|
||||
fanboy_rules_local=`cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | sed -n '4p'|awk '{print $3,$4}'`
|
||||
fanboy_rules_local1=`cat /tmp/fanboy-annoyance.txt | sed -n '4p'|awk '{print $3,$4}'`
|
||||
else
|
||||
fanboy_rules_local=`cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
fanboy_rules_local1=`cat /tmp/fanboy-annoyance.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
fi
|
||||
fanboy_nu_local=`grep -E -v "^!" /tmp/fanboy-annoyance.txt | wc -l`
|
||||
|
||||
echo_date fanboy规则本地版本号: $fanboy_rules_local
|
||||
echo_date fanboy规则在线版本号: $fanboy_rules_local1
|
||||
if [[ "$fanboy_nu_local" -gt 15000 ]]; then
|
||||
if [[ "$fanboy_rules_local" != "$fanboy_rules_local1" ]]; then
|
||||
echo_date 检测到新版本 fanboy规则 列表,开始更新...
|
||||
echo_date 将临时文件覆盖到原始 fanboy规则 文件
|
||||
mv /tmp/fanboy-annoyance.txt $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
koolproxyR_https_fanboy=1
|
||||
break
|
||||
else
|
||||
echo_date 检测到 fanboy规则 本地版本号和在线版本号相同,那还更新个毛啊!
|
||||
fi
|
||||
else
|
||||
echo_date fanboy规则 文件下载失败!
|
||||
fi
|
||||
done
|
||||
else
|
||||
echo_date 未打开 fanboy规则 的更新开关!
|
||||
fi
|
||||
|
||||
rm -rf /tmp/fanboy-annoyance.txt
|
||||
rm -rf /tmp/yhosts.txt
|
||||
rm -rf /tmp/easylistchina.txt
|
||||
|
||||
if [[ "$koolproxyR_https_fanboy" == "1" ]]; then
|
||||
echo_date 正在优化 fanboy规则。。。。。
|
||||
# 删除导致KP崩溃的规则
|
||||
# 听说高手?都打的很多、这样才能体现技术
|
||||
sed -i '/^\$/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/\*\$/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给三大视频网站放行 由kp.dat负责
|
||||
sed -i '/youku.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/iqiyi.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/qq.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/g.alicdn.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/tudou.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/gtimg.cn/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给知乎放行
|
||||
sed -i '/zhihu.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
|
||||
|
||||
# 将规则转化成kp能识别的https
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep "^||" | sed 's#^||#||https://#g' >> $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 移出https不支持规则domain=
|
||||
sed -i 's/\(,domain=\).*//g' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i 's/\(\$domain=\).*//g' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i 's/\(domain=\).*//g' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/\^$/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/\^\*\.gif/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/\^\*\.jpg/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep "^||" | sed 's#^||#||http://#g' >> $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep -i '^[0-9a-z]'| grep -v '^http'| sed 's#^#https://#g' >> $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep -i '^[0-9a-z]'| grep -v '^http'| sed 's#^#http://#g' >> $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep -i '^[0-9a-z]'| grep -i '^http' >> $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
|
||||
|
||||
# 给github放行
|
||||
sed -i '/github/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 给api.twitter.com的https放行
|
||||
sed -i '/twitter.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 给facebook.com的https放行
|
||||
sed -i '/facebook.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/fbcdn.net/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 给 instagram.com 放行
|
||||
sed -i '/instagram.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 给 twitch.tv 放行
|
||||
sed -i '/twitch.tv/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 删除可能导致卡顿的HTTPS规则
|
||||
sed -i '/\.\*\//d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
# 给国内三大电商平台放行
|
||||
sed -i '/jd.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/taobao.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
sed -i '/tmall.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt
|
||||
|
||||
# 删除不必要信息重新打包 15 表示从第15行开始 $表示结束
|
||||
sed -i '15,$d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 合二归一
|
||||
cat $KSROOT/koolproxy/data/rules/fanboy-annoyance_https.txt >> $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 删除可能导致kpr卡死的神奇规则
|
||||
sed -i '/https:\/\/\*/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给 netflix.com 放行
|
||||
sed -i '/netflix.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给 tvbs.com 放行
|
||||
sed -i '/tvbs.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/googletagmanager.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给 microsoft.com 放行
|
||||
sed -i '/microsoft.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 给apple的https放行
|
||||
sed -i '/apple.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
sed -i '/mzstatic.com/d' $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
# 终极 https 卡顿优化 grep -n 显示行号 awk -F 分割数据 sed -i "${del_rule}d" 需要""" 和{}引用变量
|
||||
# 当 koolproxyR_del_rule 是1的时候就一直循环,除非 del_rule 变量为空了。
|
||||
koolproxyR_del_rule=1
|
||||
while [ $koolproxyR_del_rule = 1 ];do
|
||||
del_rule=`cat $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt | grep -n 'https://' | grep '\*' | grep -v '/\*'| grep -v '\^\*' | grep -v '\*\=' | grep -v '\$s\@' | grep -v '\$r\@'| awk -F":" '{print $1}' | sed -n '1p'`
|
||||
if [[ "$del_rule" != "" ]]; then
|
||||
sed -i "${del_rule}d" $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt
|
||||
else
|
||||
koolproxyR_del_rule=0
|
||||
fi
|
||||
done
|
||||
|
||||
cp $KSROOT/koolproxy/data/rules/fanboy-annoyance.txt $KSROOT/koolproxy/data/rules/fanboy.txt
|
||||
else
|
||||
echo_date 跳过优化 fanboy规则。。。。。
|
||||
fi
|
||||
|
||||
|
||||
|
||||
if [[ "$koolproxyR_https_ChinaList" == "1" ]]; then
|
||||
echo_date 正在优化 KPR主规则。。。。。
|
||||
sed -i '/^\$/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/\*\$/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给btbtt.替换过滤规则。
|
||||
sed -i 's#btbtt.\*#\*btbtt.\*#g' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给手机百度图片放行
|
||||
sed -i '/baidu.com\/it\/u/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# # 给手机百度放行
|
||||
# sed -i '/mbd.baidu.comd' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给知乎放行
|
||||
sed -i '/zhihu.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给apple的https放行
|
||||
sed -i '/apple.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/mzstatic.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
|
||||
|
||||
|
||||
# 将规则转化成kp能识别的https
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep "^||" | sed 's#^||#||https://#g' >> $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
# 移出https不支持规则domain=
|
||||
sed -i 's/\(,domain=\).*//g' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i 's/\(\$domain=\).*//g' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i 's/\(domain=\).*//g' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i '/\^$/d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i '/\^\*\.gif/d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i '/\^\*\.jpg/d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
|
||||
|
||||
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep "^||" | sed 's#^||#||http://#g' >> $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep -i '^[0-9a-z]'| grep -v '^http'| sed 's#^#https://#g' >> $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep -i '^[0-9a-z]'| grep -v '^http'| sed 's#^#http://#g' >> $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep -i '^[0-9a-z]'| grep -i '^http' >> $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
# 给facebook.com的https放行
|
||||
sed -i '/facebook.com/d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
sed -i '/fbcdn.net/d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
# 删除可能导致卡顿的HTTPS规则
|
||||
sed -i '/\.\*\//d' $KSROOT/koolproxy/data/rules/easylistchina_https.txt
|
||||
|
||||
|
||||
|
||||
# 删除不必要信息重新打包 15 表示从第15行开始 $表示结束
|
||||
sed -i '6,$d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 合二归一
|
||||
cat $KSROOT/koolproxy/data/rules/easylistchina_https.txt >> $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给三大视频网站放行 由kp.dat负责
|
||||
sed -i '/youku.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/iqiyi.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/g.alicdn.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/tudou.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/gtimg.cn/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给https://qq.com的html规则放行
|
||||
sed -i '/qq.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 删除可能导致kpr卡死的神奇规则
|
||||
sed -i '/https:\/\/\*/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给国内三大电商平台放行
|
||||
sed -i '/jd.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/taobao.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/tmall.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给 netflix.com 放行
|
||||
sed -i '/netflix.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给 tvbs.com 放行
|
||||
sed -i '/tvbs.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
sed -i '/googletagmanager.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 给 microsoft.com 放行
|
||||
sed -i '/microsoft.com/d' $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
# 终极 https 卡顿优化 grep -n 显示行号 awk -F 分割数据 sed -i "${del_rule}d" 需要""" 和{}引用变量
|
||||
# 当 koolproxyR_del_rule 是1的时候就一直循环,除非 del_rule 变量为空了。
|
||||
koolproxyR_del_rule=1
|
||||
while [ $koolproxyR_del_rule = 1 ];do
|
||||
del_rule=`cat $KSROOT/koolproxy/data/rules/easylistchina.txt | grep -n 'https://' | grep '\*' | grep -v '/\*'| grep -v '\^\*' | grep -v '\*\=' | grep -v '\$s\@' | grep -v '\$r\@'| awk -F":" '{print $1}' | sed -n '1p'`
|
||||
if [[ "$del_rule" != "" ]]; then
|
||||
sed -i "${del_rule}d" $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
else
|
||||
koolproxyR_del_rule=0
|
||||
fi
|
||||
done
|
||||
#cat $KSROOT/koolproxy/data/rules/kpr_our_rule.txt >> $KSROOT/koolproxy/data/rules/easylistchina.txt
|
||||
|
||||
else
|
||||
echo_date 跳过优化 KPR主规则。。。。。
|
||||
fi
|
||||
|
||||
|
||||
if [[ "$koolproxyR_https_mobile" == "1" ]]; then
|
||||
# 删除不必要信息重新打包 0-11行 表示从第15行开始 $表示结束
|
||||
# sed -i '1,11d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
echo_date 正在优化 补充规则yhosts。。。。。
|
||||
|
||||
# 开始Kpr规则化处理
|
||||
cat $KSROOT/koolproxy/data/rules/yhosts.txt > $KSROOT/koolproxy/data/rules/yhosts_https.txt
|
||||
sed -i 's/^127.0.0.1\ /||https:\/\//g' $KSROOT/koolproxy/data/rules/yhosts_https.txt
|
||||
cat $KSROOT/koolproxy/data/rules/yhosts.txt >> $KSROOT/koolproxy/data/rules/yhosts_https.txt
|
||||
sed -i 's/^127.0.0.1\ /||http:\/\//g' $KSROOT/koolproxy/data/rules/yhosts_https.txt
|
||||
# 处理tvbox.txt本身规则。
|
||||
sed -i 's/^127.0.0.1\ /||/g' /tmp/tvbox.txt
|
||||
# 合二归一
|
||||
cat $KSROOT/koolproxy/data/rules/yhosts_https.txt > $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
cat /tmp/tvbox.txt >> $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
rm -rf /tmp/tvbox.txt
|
||||
|
||||
|
||||
# 此处对yhosts进行单独处理
|
||||
sed -i 's/^@/!/g' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i 's/^#/!/g' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/localhost/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/broadcasthost/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/broadcasthost/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/cn.bing.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给三大视频网站放行 由kp.dat负责
|
||||
sed -i '/youku.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/iqiyi.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/g.alicdn.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/tudou.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/gtimg.cn/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
|
||||
|
||||
# 给知乎放行
|
||||
sed -i '/zhihu.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给https://qq.com的html规则放行
|
||||
sed -i '/qq.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给github的https放行
|
||||
sed -i '/github/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给apple的https放行
|
||||
sed -i '/apple.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/mzstatic.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给api.twitter.com的https放行
|
||||
sed -i '/twitter.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给facebook.com的https放行
|
||||
sed -i '/facebook.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/fbcdn.net/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给 instagram.com 放行
|
||||
sed -i '/instagram.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 删除可能导致kpr卡死的神奇规则
|
||||
sed -i '/https:\/\/\*/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给国内三大电商平台放行
|
||||
sed -i '/jd.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/taobao.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/tmall.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给 netflix.com 放行
|
||||
sed -i '/netflix.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给 tvbs.com 放行
|
||||
sed -i '/tvbs.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
sed -i '/googletagmanager.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 给 microsoft.com 放行
|
||||
sed -i '/microsoft.com/d' $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
# 终极 https 卡顿优化 grep -n 显示行号 awk -F 分割数据 sed -i "${del_rule}d" 需要""" 和{}引用变量
|
||||
# 当 koolproxyR_del_rule 是1的时候就一直循环,除非 del_rule 变量为空了。
|
||||
koolproxyR_del_rule=1
|
||||
while [ $koolproxyR_del_rule = 1 ];do
|
||||
del_rule=`cat $KSROOT/koolproxy/data/rules/yhosts.txt | grep -n 'https://' | grep '\*' | grep -v '/\*'| grep -v '\^\*' | grep -v '\*\=' | grep -v '\$s\@' | grep -v '\$r\@'| awk -F":" '{print $1}' | sed -n '1p'`
|
||||
if [[ "$del_rule" != "" ]]; then
|
||||
sed -i "${del_rule}d" $KSROOT/koolproxy/data/rules/yhosts.txt
|
||||
else
|
||||
koolproxyR_del_rule=0
|
||||
fi
|
||||
done
|
||||
|
||||
|
||||
else
|
||||
echo_date 跳过优化 补充规则yhosts。。。。。
|
||||
fi
|
||||
# 删除临时文件
|
||||
rm -rf $KSROOT/koolproxy/data/rules/*_https.txt
|
||||
#rm $KSROOT/koolproxy/data/rules/kpr_our_rule.txt
|
||||
|
||||
|
||||
|
||||
echo_date 所有规则更新并优化完毕!
|
||||
echo_date =======================================================================================================
|
||||
easylist_rules_local=`cat /usr/share/koolproxy/data/rules/easylistchina.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
fanboy_rules_local=`cat /usr/share/koolproxy/data/rules/fanboy.txt | sed -n '3p'|awk '{print $3,$4}'`
|
||||
replenish_rules_local=`cat /usr/share/koolproxy/data/rules/yhosts.txt | sed -n '2p' | cut -d "=" -f2`
|
||||
echo $(date "+%F %T"): -------------------easylist version $easylist_rules_local >>$LOGFILE
|
||||
echo $(date "+%F %T"): -------------------fanboy version $fanboy_rules_local >>$LOGFILE
|
||||
echo $(date "+%F %T"): -------------------yhosts version $replenish_rules_local >>$LOGFILE
|
||||
|
||||
echo $(date "+%F %T"): ------------------- 内置规则更新成功! ------------------- >>$LOGFILE
|
||||
|
||||
RESTART_KOOLPROXY=true
|
||||
}
|
||||
|
||||
update_rss_rules() {
|
||||
cp $KP_DIR/data/user.txt $KP_DIR/data/rules/user.txt
|
||||
config_load $CONFIG
|
||||
config_foreach __update_rule rss_rule
|
||||
}
|
||||
|
||||
|
||||
update_adb_host() {
|
||||
/usr/sbin/adblockplus >>$LOGFILE 2>&1 &
|
||||
if [ "$?" == "0" ]; then
|
||||
RESTART_DNSMASQ=true
|
||||
fi
|
||||
}
|
||||
|
||||
# main process
|
||||
init_env
|
||||
limit_log $LOGFILE
|
||||
|
||||
#update_kpr_rules
|
||||
kpr_update_rules
|
||||
|
||||
|
||||
# update user rules
|
||||
update_rss_rules
|
||||
|
||||
|
||||
koolproxy_mode=$(config_t_get global koolproxy_mode 1)
|
||||
koolproxy_host=$(config_t_get global koolproxy_host 0)
|
||||
|
||||
# update ADB Plus Host
|
||||
if [ "$koolproxy_mode" == "2" ] && [ "$koolproxy_host" == "1" ];then
|
||||
update_adb_host
|
||||
fi
|
||||
|
||||
if [ $RESTART_KOOLPROXY ]; then
|
||||
restart_koolproxy
|
||||
echo $(date "+%F %T"): 重启koolproxy进程 >>$LOGFILE
|
||||
echo >>$LOGFILE
|
||||
fi
|
||||
|
||||
init_env
|
||||
|
||||
|
||||
|
194
luci-app-koolproxyR/koolproxy.txt
Normal file
@ -0,0 +1,194 @@
|
||||
koolproxy插件/固件开发文档1.3
|
||||
更新日期:2017年7月7日(koolproxy 3.6.1)
|
||||
|
||||
================================================================================================
|
||||
声明:
|
||||
KoolProxy 是一个免费软件,著作权归属 KoolProxy.com,用户可以非商业性地复制和使用 KoolProxy,但禁止将 KoolProxy 用于商业用途。
|
||||
KoolProxy 可以对 https 网络数据进行识别代理,使用 https 功能的用户需要自己提供相关证书,本程序提供的证书生成脚本仅供用户参考,证书的保密工作由用户自行负责。
|
||||
使用本软件的风险由用户自行承担,在适用法律允许的最大范围内,对因使用本产品所产生的损害及风险,包括但不限于直接或间接的个人损害、商业赢利的丧失、贸易中断、商业信息的丢失或任何其它经济损失,KoolProxy.com 不承担任何责任。
|
||||
|
||||
================================================================================================
|
||||
KoolProxy By Xiaobao & Crwnet v3.6.1
|
||||
|
||||
USAGE:
|
||||
koolproxy [options] [arguments...]
|
||||
|
||||
OPTIONS:
|
||||
-p value listen port, default value is 3000
|
||||
-l value log level (0:DEBUG, 1:INFO, 2:AD, 3:WARNING, 4:ERROR), default value is ERROR
|
||||
-c value thread count, default value is the number of cpus
|
||||
-b value data path, default value is './data'
|
||||
-d run as daemon mode
|
||||
-v show version
|
||||
-h show help
|
||||
|
||||
ADVANCED:
|
||||
--cert generate ssl cert
|
||||
--ipv6 enable ipv6, works for ipv6 nat mode
|
||||
--video | -e video mode, load video rules only
|
||||
--mark mark mode, set the socket mark(src ip) when connect to remote host. requires the CAP_NET_ADMIN capability
|
||||
--ttl value ttl mode, set the socket ttl when connect to remote host. default value is 0 (disable)
|
||||
|
||||
================================================================================================
|
||||
交流地址:
|
||||
1 QQ群1: 595300867
|
||||
2 QQ群2: 203726739
|
||||
3 TG群: https://t.me/joinchat/AAAAAD-tO7GPvfOU131_vg
|
||||
4 更新日志:http://koolshare.cn/thread-64086-1-1.html
|
||||
|
||||
================================================================================================
|
||||
#koolproxy部署文件目录参考1(使用openssl生成证书)
|
||||
.
|
||||
├── data
|
||||
│ ├── gen_ca.sh #证书生成脚本
|
||||
│ ├── koolproxy_ipset.conf #ipset名单
|
||||
│ ├── openssl.cnf #证书生成所用配置文件
|
||||
│ ├── rules #规则存放文件夹
|
||||
│ │ ├── kp.dat #视频规则
|
||||
│ │ ├── koolproxy.txt #静态规则
|
||||
│ │ ├── daily.txt #每日规则
|
||||
│ │ └── user.txt #自定义规则
|
||||
│ └── version #插件版本号(merlin)
|
||||
└── koolproxy #koolproxy二进制(为了保证二进制顺利更新,请保证目录可写)
|
||||
|
||||
1 证书生成使用命令 sh gen_ca.sh,该脚本会调用系统内的openssl来生成证书,运行成功后会自动创建data/private data/cert目录
|
||||
私钥和公钥会分别存在data/private data/cert目录下,使用http://110.110.110.110会下载路由器内的证书
|
||||
|
||||
------------------------------------------------------------------------------------------------
|
||||
#koolproxy部署文件目录参考2(使用koolproxy生成证书)
|
||||
.
|
||||
└── koolproxy #koolproxy二进制(为了保证二进制顺利更新,请保证目录可写)
|
||||
1 因为规则文件会由koolproxy自动下载,下载后会自动创建data/rules目录
|
||||
2 使用koolproxy --cert命令可以生成证书,运行成功后会自动创建data/private data/cert目录
|
||||
私钥和公钥会分别存在data/private data/cert目录下,使用http://110.110.110.110会下载路由器内的证书
|
||||
因为mbedtls性能原因,在非软路由机器上用koolproxy --cert生成证书需要时间较长,请耐心等待
|
||||
|
||||
================================================================================================
|
||||
说明:
|
||||
1 koolproxy启动会自动检测规则更新,如果没有./data/rules文件夹,会自己创建并下载规则到此处
|
||||
2 koolproxy启动后会检测二进制文件更新,如果有更新,会替换./koolproxy,并且由父进程重启koolproxy,以后每20分钟检测一次更新
|
||||
3 现在不支持规则订阅了,只能识别kp.dat, koolproxy.txt, user.txt,daily.txt,需要自定义规则的可以修改user.txt
|
||||
|
||||
# 二进制下载固定地址
|
||||
https://koolproxy.com/downloads/i386
|
||||
https://koolproxy.com/downloads/x86_64
|
||||
https://koolproxy.com/downloads/arm
|
||||
https://koolproxy.com/downloads/mips
|
||||
https://koolproxy.com/downloads/mipsel
|
||||
|
||||
# 规则下载固定地址
|
||||
https://kprule.com/koolproxy.txt
|
||||
https://kprule.com/daily.txt
|
||||
https://kprule.com/kp.dat
|
||||
https://kprule.com/user.txt
|
||||
|
||||
# 规则下载对应的CDN地址
|
||||
https://kprules.b0.upaiyun.com/koolproxy.txt
|
||||
https://kprules.b0.upaiyun.com/daily.txt
|
||||
https://kprules.b0.upaiyun.com/kp.dat
|
||||
https://kprules.b0.upaiyun.com/user.txt
|
||||
|
||||
# 二进制文件和规则 github备份地址:
|
||||
二进制:https://github.com/koolproxy/koolproxy-bin (已作废)
|
||||
规则:https://github.com/koolproxy/koolproxy_rules (已作废)
|
||||
|
||||
|
||||
1 建议从上面的链接获取最新的二进制和基本的规则文件,然后按照上面的目录结构来部署
|
||||
2 如果不需要https过滤,只需要一个koolproxy程序就足够了,data文件夹和rules文件夹都会自己创建。
|
||||
3 koolproxy.txt内有视频规则、静态规则、每日规则的更新日期,可以用于提取并显示到界面
|
||||
|
||||
================================================================================================
|
||||
koolproxy运行:
|
||||
|
||||
1 在koolproxy主程序目录运行,例如merlin固件下运行:cd /koolshare/koolproxy && koolproxy -d
|
||||
2 不在koolproxy主程序目录运行(例如将koolproxy放在环境变量中),例如merlin固件下运行:koolproxy -b /koolshare/koolproxy -d -b为data路径
|
||||
其它运行方式可能会造成koolproxy识别不到data目录而无法加载规则
|
||||
koolproxy运行后默认会使用端口3000作为透明代理端口,需要利用iptables将数据导到端口3000才能发挥作用。
|
||||
|
||||
视频模式:
|
||||
1 使用命令koolproxy -e 即可开启
|
||||
2 开启后只会加载视频规则kp.dat和user.txt
|
||||
|
||||
调试模式:
|
||||
1 使用命令koolproxy -l0 即可开启,l后面的数字代表不同的日志详细程度
|
||||
2 需要检查规则命中行数可以需要使用-l2
|
||||
|
||||
ttl功能:
|
||||
1 使用命令koolproxy --ttl 160 即可开启ttl功能,后面的数值代表ttl大小
|
||||
2 ttl功能开启后,koolproxy会对经过它的所有数据ttl进行调整,可以利用iptables的match ttl功能数据进行匹配
|
||||
|
||||
mark功能:
|
||||
1 使用命令koolproxy --mark 即可开启mark功能
|
||||
2 mark功能开启后,koolproxy会对经过它的所有数据打上标记,mark值等于该数据的源ip转换为十六进制的值
|
||||
3 例如局域网内192.168.1.100的数据,将会被打上0xc0a80164的mark(192 = c0, 168 = a8, 1 = 01, 100 = 64 )
|
||||
4 开发者可以用此功和SS配合,达到既科学上网,又能过滤这些科学上网的流量,还不影响科学上网访问控制的功能
|
||||
5 ip转换为mark值参考命令:echo 192.168.1.100 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("%02x\n", $4)}'
|
||||
|
||||
================================================================================================
|
||||
ss + kp过滤方案(2017年7月7日):
|
||||
|
||||
方案1(优先SS,其次KP,不推荐):
|
||||
1 在NAT PREROUTING链内,SS在前,KP在后,流量将先走SS,经过SS分流后,国外流量走ss-redir,实现翻墙;
|
||||
2 而剩下国内流量在PREROUTING链内继续往下匹配到koolrpxy规则,流量最终走koolproxy,实现过滤。
|
||||
结果:koolproxy只能过滤国内流量(SS剩下的)。
|
||||
|
||||
方案2(优先KP,其次SS,不推荐);
|
||||
1 在NAT PREROUTING链内,KP在前,SS在后,流量将先走KP,实现过滤;
|
||||
2 为了SS能拿到KP过滤后的数据,使用match ttl匹配,在OUTPUT链内将流量全部给SS,实现翻墙;
|
||||
结果:因为在OUTPUT链内没有源ip信息,流量给SS后无法匹配到源ip,因此SS失去了acl(访问控制)功能。
|
||||
|
||||
方案3 (优先kp,其次SS,推荐);
|
||||
为便于理解,以下iptables配置只展示流量经过顺序,不是iptables的创建顺序,PREROUTING内规则的创建实际上应该在最后
|
||||
0 koolproxy默认开启ttl和mark功能 KoolProxy --ttl 160 --mark -d(固件不支持ttl的仅开启mark也行: KoolProxy --mark -d)
|
||||
1 在NAT PREROUTING链内,KP在前,SS在后,KP开启--mark,流量将先走KP(80,443),实现过滤,过滤后每个主机会被打上不同的mark;
|
||||
#KP在前,所有tcp流量全部交给KOOLPROXY链
|
||||
-A PREROUTING -p tcp -j KOOLPROXY
|
||||
#SS在后,在kp开启的时候,只能拿到非80,443的流量,在kp关闭后,可以拿到所有端口的流量
|
||||
-A PREROUTING -p tcp -j SHADOWSOCKS
|
||||
|
||||
2 例如局域网内192.168.1.100主机的数据经过kp过滤后,将会被打上0xc0a80164的mark(192 = c0, 168 = a8, 1 = 01, 100 = 64 );
|
||||
#创建KOOLPROXY链,用于白名单和访问控制
|
||||
-N KOOLPROXY
|
||||
#创建KOOLPROXY_HTTP链,用于过滤http流量
|
||||
-N KOOLPROXY_HTTP
|
||||
#创建KOOLPROXY_HTTPS链,用于过滤https流量
|
||||
-N KOOLPROXY_HTTPS
|
||||
#局域网和保留地址不走kp
|
||||
-A KOOLPROXY -m set --match-set white_kp_list dst -j RETURN
|
||||
#主机192.168.1.100需要https过滤
|
||||
-A KOOLPROXY -s 192.168.1.100/32 -p tcp -g KOOLPROXY_HTTPS
|
||||
#其它主机过滤http流量
|
||||
-A KOOLPROXY -p tcp -j KOOLPROXY_HTTP
|
||||
|
||||
3 为了SS能拿到数据,在NAT OUTPUT链中,使用match ttl匹配,在OUTPUT链内将流量全部给SHADOWSOCKS_EXT链;
|
||||
#创建SHADOWSOCKS_EXT链,用于开启kp情况下ss的访问控制实现
|
||||
-N SHADOWSOCKS_EXT
|
||||
#使用ttl匹配将KP过滤后的数据转到SHADOWSOCKS_EXT链(如果固件不支持ttl匹配,使用下面的命令)
|
||||
-A OUTPUT -p tcp -m ttl --ttl-eq 160 -j SHADOWSOCKS_EXT
|
||||
#如果固件不支持ttl match,可以用mark匹配ip地址的前三位(用0xffffff00作为掩码的形式),来将KP过滤后的数据转到SHADOWSOCKS_EXT链
|
||||
# echo 192.168.1 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("00/0xffffff00\n")}' = 0xc0a80100/0xffffff00
|
||||
-A OUTPUT -p tcp -m mark --mark 0xc0a80100/0xffffff00 -j SHADOWSOCKS_EXT
|
||||
|
||||
4 如果开启了acl,比如需要192.168.1.75不走SS(全端口),192.168.1.246走gfwlist模式(80,443端口),192.168.1.214走大陆白名单模式(22,80,443端口),剩余主机全部走大陆白名单模式(全端口):
|
||||
#主机192.168.1.75(0xc0a8014b),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,而未能翻墙(RETURN)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m mark --mark 0xc0a8014b -j RETURN
|
||||
#主机192.168.1.246(0xc0a801f6),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_GFW链,实现gfwlist模式翻墙(80,443端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m multiport --dports 80,443 -m mark --mark 0xc0a801f6 -g SHADOWSOCKS_GFW
|
||||
#主机192.168.1.214(0xc0a801f6),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_CHN链,实现大陆白名单模式翻墙(22,80,443端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m multiport --dports 22,,80,443 -m mark --mark 0xc0a801d6 -g SHADOWSOCKS_CHN
|
||||
#剩余的主机,流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_CHN链,实现大陆白名单模式翻墙(全端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -j SHADOWSOCKS_CHN
|
||||
|
||||
情形:
|
||||
1 当SS开启,kp未开启:所有流量走ss PREROUTING过,经过分流后,国内的流量在经过OUTPUT的时候,因为KP没开,数据不会匹配到ttl值(或者没匹配到mark值),所以不会过滤广告,翻墙正常
|
||||
2 当KP开启,SS未开启,所有流量走kp PREROUTING过,广告过滤正常
|
||||
3 当SS开启,翻墙和acl工作正常的时候,开启KP:KP在PREROUTING内插入到SS前面,会先得到流量,广告过滤正常
|
||||
4 当KP开启,过滤广告正常的时候,开启SS:SS从原来的从PREROUTING拿流量变成从OUTPUT内拿流量,翻墙和acl会同样正常
|
||||
5 当KP和SS都开启,此时关闭SS,kp过滤广告正常
|
||||
6 当KP和SS都开启,此时关闭KP,ss翻墙和acl正常
|
||||
|
||||
总结:
|
||||
使用 ttl + mark (或者纯mark)的方式,可以实现原先很难实现的过滤经过SS流量的广告
|
||||
主要的改动在于给SS预置好OUTPUT和SHADOWSOCKS_EXT规则链,当kp启用时,它们就会工作,kp关闭时,不会影响正常数据
|
||||
次要的改动就是给koolproxy默认开启ttl + mark(或者纯mark)功能
|
||||
================================================================================================
|
13
luci-app-koolproxyR/koolproxyupdate.sh
Executable file
@ -0,0 +1,13 @@
|
||||
wget 'https://raw.githubusercontent.com/user1121114685/koolproxyR_rule_list/master/kp.dat' -O files/usr/share/koolproxy/data/rules/kp.dat
|
||||
wget 'https://raw.githubusercontent.com/user1121114685/koolproxyR/master/koolproxyR/koolproxyR/data/rules/yhosts.txt' -O files/usr/share/koolproxy/data/rules/yhosts.txt
|
||||
wget 'https://dev.tencent.com/u/shaoxia1991/p/cjxlist/git/raw/master/cjx-annoyance.txt' -O files/usr/share/koolproxy/data/rules/fanboy.txt
|
||||
wget 'https://easylist-downloads.adblockplus.org/easylistchina.txt' -O files/usr/share/koolproxy/data/rules/easylistchina.txt
|
||||
|
||||
wget 'https://raw.githubusercontent.com/user1121114685/koolproxyR/master/koolproxyR/koolproxyR/data/rules/user.txt' -O files/usr/share/koolproxy/data/user.txt
|
||||
cp files/usr/share/koolproxy/data/user.txt files/usr/share/koolproxy/data/rules/user.txt
|
||||
wget 'https://raw.githubusercontent.com/user1121114685/koolproxyR/master/koolproxyR/koolproxyR/data/koolproxyR_ipset.conf' -O files/usr/share/koolproxy/koolproxy_ipset.conf
|
||||
|
||||
wget https://easylist-downloads.adblockplus.org/easylistchina+easylist.txt -O- | grep ^\|\|[^\*]*\^$ | sed -e 's:||:address\=\/:' -e 's:\^:/0\.0\.0\.0:' > files/usr/share/koolproxy/dnsmasq.adblock
|
||||
sed -i '/youku/d' files/usr/share/koolproxy/dnsmasq.adblock
|
||||
sed -i '/[1-9]\{1,3\}\.[1-9]\{1,3\}\.[1-9]\{1,3\}\.[1-9]\{1,3\}/d' files/usr/share/koolproxy/dnsmasq.adblock
|
||||
|
622
luci-app-oled/LICENSE
Normal file
@ -0,0 +1,622 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
22
luci-app-oled/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2020 Nate Ding
|
||||
#
|
||||
# This is free software, licensed under the GUN General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
PKG_NAME:=luci-app-oled
|
||||
LUCI_Title:=LuCI support for ssd1306 0.91\' 138x32 display
|
||||
LUCI_PKGARCH:=all
|
||||
LUCI_DEPENDS:=+i2c-tools +coreutils-nohup +libuci
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=1.0
|
||||
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_LINCESE_FILES:=LICENSE
|
||||
PKF_MAINTAINER:=natelol <natelol@github.com>
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
80
luci-app-oled/README.md
Normal file
@ -0,0 +1,80 @@
|
||||
# luci-app-oled
|
||||
|
||||
This is the LuCI app written for openwrt (**tested ~~only~~ on NanoPi R2S**) which supports ssd 1306 0.91' oled display.
|
||||
|
||||
**Raspberry Pi CM4**
|
||||
|
||||
This has been tested on Raspberry Pi CM4 as described in issue [#10](https://github.com/NateLol/luci-app-oled/issues/10#issuecomment-922245476).
|
||||
You can find what revisions you need to make to have it work on your device.
|
||||
Enjoy!
|
||||
|
||||
## Features|功能
|
||||
---
|
||||
### Dispaly Info|显示信息
|
||||
|
||||
**0. Enable|开启**
|
||||
|
||||
开启oled显示。
|
||||
|
||||
**1. Autoswitch|定时开关**
|
||||
|
||||
由于夜间oled的显示屏太亮,并且也几乎不会看它,所以应邀提供定时开关的功能,选中autoswitch之后,可以设置**显示**的起始和结束时间。
|
||||
|
||||
**2. Time|时间**
|
||||
|
||||
显示时间。
|
||||
|
||||
**3. IP|IP地址**
|
||||
|
||||
显示LAN口的IP地址,记得LAN口不可以去除**桥接**选项,否则失效。由于使用的是`br-lan`,因为不同固件可能会交换`eth0`和`eth1`。
|
||||
|
||||
**4. CPU Temp|CPU温度**
|
||||
|
||||
显示CPU温度。
|
||||
|
||||
**5. CPU Freq|CPU频率**
|
||||
|
||||
显示实时CPU频率
|
||||
|
||||
**6. Network Speed|网速**
|
||||
|
||||
提供不同接口的选择,`eth0`和`eth1`,个人可以按需修改。网速单位基准为字节(Byte)而不是一般的位(bit),[MB/s, KB/s, B/s]这样显示的数字能够比较小,不至于过长。
|
||||
|
||||
**7. Display Interval|显示间隔**
|
||||
|
||||
为了延缓oled的光衰,提供屏保服务,每隔设定的时间运行一次屏保程序。
|
||||
|
||||
---
|
||||
### Screensavers|屏保
|
||||
|
||||
屏保提供不同的选择,默认推荐的是`Scroll Text|文字滚动`,其他的选择自行探索。
|
||||
|
||||
## Q&A
|
||||
|
||||
Q0. 如何使用该程序?|在那里找到luci界面?
|
||||
|
||||
A0. 该程序安装位置在luci界面的`services|服务`下的`OLED`,点击即可找到。
|
||||
|
||||
---
|
||||
|
||||
Q1. 是否会支持其他oled屏幕,例如同系列的0.96'的?
|
||||
|
||||
A1. 由于开发者身边并没有相应的屏幕去调试,所以是暂时不考虑吧。如果你想贡献代码,非常欢迎,请开PR。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Q2. 为什么我的IP地址显示错误?
|
||||
|
||||
A2. 很大原因是你修改了LAN接口的属性,例如去除了该接口的**桥接**属性。
|
||||
|
||||
---
|
||||
|
||||
|
||||
Q3. 为什么我的oled不显示?
|
||||
|
||||
A3. 很有可能是您的固件内核驱动不完整,该程序的运行需要在内核驱动中加上**kmod-i2c-xxx**,见issue [#10](https://github.com/NateLol/luci-app-oled/issues/10)。
|
||||
|
||||
---
|
||||
|
||||
如果你在使用过程中还遇到问题,请开issue。
|
17
luci-app-oled/luasrc/controller/oled.lua
Normal file
@ -0,0 +1,17 @@
|
||||
module("luci.controller.oled", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/oled") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "oled"}, alias("admin", "services", "oled", "setting"),_("OLED"), 10).dependent = true
|
||||
entry({"admin", "services", "oled", "status"}, call("act_status"))
|
||||
entry({"admin", "services", "oled", "setting"}, cbi("oled/setting"),_("Setting"),30).leaf = true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running = luci.sys.call("pgrep -f /usr/bin/oled > /dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
100
luci-app-oled/luasrc/model/cbi/oled/setting.lua
Normal file
@ -0,0 +1,100 @@
|
||||
m = Map("oled", translate("OLED"), translate("A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) with screensavers! <br /> <br /> Any issues, please go to: ")..[[<a href="https://github.com/natelol/luci-app-oled" target="_blank">luci-app-oled</a>]])
|
||||
|
||||
--m.chain("luci")
|
||||
|
||||
m:section(SimpleSection).template="oled/status"
|
||||
|
||||
s = m:section(TypedSection, "oled", translate(""))
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
|
||||
--OPTIONS
|
||||
s:tab("info", translate("Info Display"))
|
||||
s:tab("screensaver", translate("screensaver"))
|
||||
|
||||
o = s:taboption("info", Flag, "enable", translate("Enable"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "autoswitch", translate("Enable Auto switch"))
|
||||
o.default=0
|
||||
from = s:taboption("info", ListValue, "from", translate("From"))
|
||||
to = s:taboption("info", ListValue, "to", translate("To"))
|
||||
for i=0,23 do
|
||||
for j=0,30,30 do
|
||||
from:value(i*60+j,string.format("%02d:%02d",i,j))
|
||||
to:value(i*60+j,string.format("%02d:%02d",i,j))
|
||||
end
|
||||
end
|
||||
from:value(1440,"24:00")
|
||||
to:value(1440,"24:00")
|
||||
from:depends("autoswitch",'1')
|
||||
to:depends("autoswitch",'1')
|
||||
from.default=0
|
||||
to.default=1440
|
||||
|
||||
--informtion options----
|
||||
o = s:taboption("info", Flag, "date", translate("Date"), translate('Format YYYY-MM-DD HH:MM:SS'))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "lanip", translate("IP"), translate("LAN IP address"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "cputemp", translate("CPU temperature"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "cpufreq", translate("CPU frequency"))
|
||||
o.default=0
|
||||
o = s:taboption("info", Flag, "netspeed", translate("Network speed"), translate("1Mbps(m/s)=1,000Kbps(k/s)=1,000,000bps(b/s)"))
|
||||
o.default=0
|
||||
o = s:taboption("info", ListValue, "netsource", translate("which eth to monitor"))
|
||||
o:value("eth0","eth0")
|
||||
o:value("eth1","eth1")
|
||||
o:depends("netspeed",'1')
|
||||
o.default='eth0'
|
||||
o = s:taboption("info", Value, "time", translate("Display interval(s)"), translate('Screensaver will activate in set seconds'))
|
||||
o.default=0
|
||||
|
||||
--screensaver options--
|
||||
o = s:taboption("screensaver", Flag, "scroll", translate("Scroll Text"))
|
||||
o.default=1
|
||||
o = s:taboption("screensaver", Value, "text", translate("Text you want to scroll"))
|
||||
o:depends("scroll",'1')
|
||||
o.default='OPENWRT'
|
||||
o = s:taboption("screensaver", Flag, "drawline", translate("Draw Many Lines"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawrect", translate("Draw Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "fillrect", translate("Draw Multiple Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawcircle", translate("Draw Multiple Circles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawroundrect", translate("Draw a white circle, 10 pixel radius"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "fillroundrect", translate("Fill the Round Rectangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawtriangle", translate("Draw Triangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "filltriangle", translate("Fill Triangles"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "displaybitmap", translate("Display miniature bitmap"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "displayinvertnormal", translate("Invert Display Normalize it"))
|
||||
o.default=0
|
||||
o = s:taboption("screensaver", Flag, "drawbitmapeg", translate("Draw a bitmap and animate"))
|
||||
o.default=0
|
||||
|
||||
return m
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
---
|
22
luci-app-oled/luasrc/view/oled/status.htm
Normal file
@ -0,0 +1,22 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[oled]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('oled_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>OLED <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>OLED <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="oled_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
1
luci-app-oled/po/zh-cn
Symbolic link
@ -0,0 +1 @@
|
||||
zh_Hans
|
143
luci-app-oled/po/zh_Hans/oled.po
Normal file
@ -0,0 +1,143 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
msgid ""
|
||||
"A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) "
|
||||
"with screensavers! <br /> <br /> Any issues, please go to:"
|
||||
msgstr "这是一款支持在ssd1306,0.91寸,128x32像素的oled显示屏上显示你要的信息,包含屏保的程序。<br /> <br />任何问题请到:"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:24
|
||||
msgid "CPU frequency"
|
||||
msgstr "CPU频率"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:22
|
||||
msgid "CPU temperature"
|
||||
msgstr "CPU温度"
|
||||
|
||||
msgid "Scroll Text"
|
||||
msgstr "文字滚动"
|
||||
|
||||
msgid "Enable Auto switch"
|
||||
msgstr "启用定时开关"
|
||||
|
||||
msgid "From"
|
||||
msgstr "起始时间"
|
||||
|
||||
msgid "To"
|
||||
msgstr "结束时间"
|
||||
|
||||
msgid "Text you want to scroll"
|
||||
msgstr "你想要显示的文字"
|
||||
|
||||
msgid "which eth to monitor"
|
||||
msgstr "选择监控哪个网口"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Date"
|
||||
msgstr "时间"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:48
|
||||
msgid "Display miniature bitmap"
|
||||
msgstr "小图案"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Display interval(s)"
|
||||
msgstr "信息显示间隔(秒)"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Screensaver will activate in set seconds"
|
||||
msgstr "屏保每间隔设置的时间运行一次"
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:32
|
||||
msgid "Draw Many Lines"
|
||||
msgstr "直线"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:38
|
||||
msgid "Draw Multiple Circles"
|
||||
msgstr "多圆"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:36
|
||||
msgid "Draw Multiple Rectangles"
|
||||
msgstr "多方块"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:34
|
||||
msgid "Draw Rectangles"
|
||||
msgstr "方块"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:44
|
||||
msgid "Draw Triangles"
|
||||
msgstr "三角形"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:54
|
||||
msgid "Draw a bitmap and animate"
|
||||
msgstr "动图"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:52
|
||||
msgid "Draw a bitmap and animate movement"
|
||||
msgstr "变化图"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:40
|
||||
msgid "Draw a white circle, 10 pixel radius"
|
||||
msgstr "实心圆"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:15
|
||||
msgid "Enable"
|
||||
msgstr "启用"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:46
|
||||
msgid "Fill Triangles"
|
||||
msgstr "三角填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:42
|
||||
msgid "Fill the Round Rectangles"
|
||||
msgstr "方形填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Format YYYY-MM-DD HH:MM:SS"
|
||||
msgstr "日期格式 YYYY-MM-DD HH:MM:SS"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "IP"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:12
|
||||
msgid "Info Display"
|
||||
msgstr "显示信息"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:50
|
||||
msgid "Invert Display Normalize it"
|
||||
msgstr "反转"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "LAN IP address"
|
||||
msgstr "LAN地址"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:26
|
||||
msgid "Network speed"
|
||||
msgstr "网速"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:7
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:7
|
||||
msgid "OLED"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:9
|
||||
msgid "Setting"
|
||||
msgstr "设置"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:13
|
||||
msgid "screensaver"
|
||||
msgstr "屏保"
|
135
luci-app-oled/po/zh_Hant/oled.po
Normal file
@ -0,0 +1,135 @@
|
||||
msgid ""
|
||||
msgstr "Content-Type: text/plain; charset=UTF-8"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
msgid ""
|
||||
"A LuCI app that helps you config your oled display (SSD1306, 0.91', 128X32) "
|
||||
"with screensavers! <br /> <br /> Any issues, please go to:"
|
||||
msgstr "這是壹款支持在ssd1306,0.91寸,128x32像素的oled顯示屏上顯示妳要的信息,包含屏保的程序。<br /> <br />任何問題請到:"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:24
|
||||
msgid "CPU frequency"
|
||||
msgstr "CPU頻率"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:22
|
||||
msgid "CPU temperature"
|
||||
msgstr "CPU溫度"
|
||||
|
||||
msgid "Scroll Text"
|
||||
msgstr "文字滾動"
|
||||
|
||||
msgid "Text you want to scroll"
|
||||
msgstr "妳想要顯示的文字"
|
||||
|
||||
msgid "which eth to monitor"
|
||||
msgstr "選擇監控哪個網口"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Date"
|
||||
msgstr "時間"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:48
|
||||
msgid "Display miniature bitmap"
|
||||
msgstr "小圖案"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Display interval(s)"
|
||||
msgstr "信息顯示間隔(秒)"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:28
|
||||
msgid "Screensaver will activate in set seconds"
|
||||
msgstr "屏保每間隔設置的時間運行壹次"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:32
|
||||
msgid "Draw Many Lines"
|
||||
msgstr "直線"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:38
|
||||
msgid "Draw Multiple Circles"
|
||||
msgstr "多圓"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:36
|
||||
msgid "Draw Multiple Rectangles"
|
||||
msgstr "多方塊"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:34
|
||||
msgid "Draw Rectangles"
|
||||
msgstr "方塊"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:44
|
||||
msgid "Draw Triangles"
|
||||
msgstr "三角形"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:54
|
||||
msgid "Draw a bitmap and animate"
|
||||
msgstr "動圖"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:52
|
||||
msgid "Draw a bitmap and animate movement"
|
||||
msgstr "變化圖"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:40
|
||||
msgid "Draw a white circle, 10 pixel radius"
|
||||
msgstr "實心圓"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:15
|
||||
msgid "Enable"
|
||||
msgstr "啟用"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:46
|
||||
msgid "Fill Triangles"
|
||||
msgstr "三角填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:42
|
||||
msgid "Fill the Round Rectangles"
|
||||
msgstr "方形填充"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:18
|
||||
msgid "Format YYYY-MM-DD HH:MM:SS"
|
||||
msgstr "日期格式 YYYY-MM-DD HH:MM:SS"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "IP"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:12
|
||||
msgid "Info Display"
|
||||
msgstr "顯示信息"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:50
|
||||
msgid "Invert Display Normalize it"
|
||||
msgstr "反轉"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:20
|
||||
msgid "LAN IP address"
|
||||
msgstr "LAN地址"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:26
|
||||
msgid "Network speed"
|
||||
msgstr "網速"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:7
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:1
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:7
|
||||
msgid "OLED"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/view/oled/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/controller/oled.lua:9
|
||||
msgid "Setting"
|
||||
msgstr "設置"
|
||||
|
||||
#: ../../package/new/luci-app-oled/luasrc/model/cbi/oled/setting.lua:13
|
||||
msgid "screensaver"
|
||||
msgstr "屏保"
|
25
luci-app-oled/root/etc/config/oled
Normal file
@ -0,0 +1,25 @@
|
||||
config oled
|
||||
option drawline '0'
|
||||
option drawrect '0'
|
||||
option fillrect '0'
|
||||
option drawcircle '0'
|
||||
option drawroundrect '0'
|
||||
option fillroundrect '0'
|
||||
option drawtriangle '0'
|
||||
option filltriangle '0'
|
||||
option displaybitmap '0'
|
||||
option displayinvertnormal '0'
|
||||
option drawbitmapeg '0'
|
||||
option date '1'
|
||||
option netspeed '0'
|
||||
option lanip '1'
|
||||
option cpufreq '1'
|
||||
option cputemp '1'
|
||||
option time '60'
|
||||
option enable '0'
|
||||
option from '0'
|
||||
option to '1440'
|
||||
option autoswitch '0'
|
||||
option scroll '1'
|
||||
option text 'OPENWRT'
|
||||
option netsource 'eth0'
|
140
luci-app-oled/root/etc/init.d/oled
Executable file
@ -0,0 +1,140 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=1OO
|
||||
|
||||
PROG=/usr/bin/oled
|
||||
|
||||
stop() {
|
||||
kill -2 $(pgrep /usr/bin/oled)
|
||||
kill -9 $(pgrep -f /usr/sbin/netspeed)
|
||||
echo "oled exit..."
|
||||
}
|
||||
|
||||
start() {
|
||||
enabled=$(uci get oled.@oled[0].enable)
|
||||
if [ $enabled -eq 0 ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
autoswitch=$(uci get oled.@oled[0].autoswitch)
|
||||
from=$(uci get oled.@oled[0].from)
|
||||
to=$(uci get oled.@oled[0].to)
|
||||
|
||||
if [ ${autoswitch} -eq 1 ]; then
|
||||
hour=$(date +"%H")
|
||||
min=$(date +"%M")
|
||||
ihour=`expr $hour + 0`
|
||||
imin=`expr $min + 0`
|
||||
now=$(($ihour*60+$imin))
|
||||
if [[ $now -lt $from || $now -gt $to ]]; then
|
||||
stop
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
#crontab daemon
|
||||
if ! grep "/etc/init.d/oled \+restart" /etc/crontabs/root >/dev/null 2>&1; then
|
||||
echo "*/5 * * * * /etc/init.d/oled restart >/dev/null 2>&1" >> /etc/crontabs/root
|
||||
fi
|
||||
|
||||
date=$(uci get oled.@oled[0].date)
|
||||
lanip=$(uci get oled.@oled[0].lanip)
|
||||
cputemp=$(uci get oled.@oled[0].cputemp)
|
||||
cpufreq=$(uci get oled.@oled[0].cpufreq)
|
||||
netspeed=$(uci get oled.@oled[0].netspeed)
|
||||
time=$(uci get oled.@oled[0].time)
|
||||
drawline=$(uci get oled.@oled[0].drawline)
|
||||
drawrect=$(uci get oled.@oled[0].drawrect)
|
||||
fillrect=$(uci get oled.@oled[0].fillrect)
|
||||
drawcircle=$(uci get oled.@oled[0].drawcircle)
|
||||
drawroundrect=$(uci get oled.@oled[0].drawroundrect)
|
||||
fillroundrect=$(uci get oled.@oled[0].fillroundrect)
|
||||
drawtriangle=$(uci get oled.@oled[0].drawtriangle)
|
||||
filltriangle=$(uci get oled.@oled[0].filltriangle)
|
||||
displaybitmap=$(uci get oled.@oled[0].displaybitmap)
|
||||
displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal)
|
||||
drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg)
|
||||
scroll=$(uci get oled.@oled[0].scroll)
|
||||
text=$(uci get oled.@oled[0].text)
|
||||
netsource=$(uci get oled.@oled[0].netsource)
|
||||
|
||||
|
||||
if [ ${netspeed} -eq 1 ]; then
|
||||
nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 &
|
||||
else
|
||||
kill -9 $(pgrep -f /usr/sbin/netspeed)
|
||||
rm -f /tmp/netspeed
|
||||
fi
|
||||
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 1 > /dev/null 2>&1 &
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
restart(){
|
||||
enabled=$(uci get oled.@oled[0].enable)
|
||||
pgrep -f ${PROG} >/dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
if [ $enabled -eq 1 ]; then
|
||||
autoswitch=$(uci get oled.@oled[0].autoswitch)
|
||||
from=$(uci get oled.@oled[0].from)
|
||||
to=$(uci get oled.@oled[0].to)
|
||||
if [ ${autoswitch} -eq 1 ]; then
|
||||
hour=$(date +"%H")
|
||||
min=$(date +"%M")
|
||||
ihour=`expr $hour + 0`
|
||||
imin=`expr $min + 0`
|
||||
now=$(($ihour*60+$imin))
|
||||
if [[ $now -lt $from || $now -gt $to ]]; then
|
||||
stop
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
date=$(uci get oled.@oled[0].date)
|
||||
lanip=$(uci get oled.@oled[0].lanip)
|
||||
cputemp=$(uci get oled.@oled[0].cputemp)
|
||||
cpufreq=$(uci get oled.@oled[0].cpufreq)
|
||||
netspeed=$(uci get oled.@oled[0].netspeed)
|
||||
time=$(uci get oled.@oled[0].time)
|
||||
drawline=$(uci get oled.@oled[0].drawline)
|
||||
drawrect=$(uci get oled.@oled[0].drawrect)
|
||||
fillrect=$(uci get oled.@oled[0].fillrect)
|
||||
drawcircle=$(uci get oled.@oled[0].drawcircle)
|
||||
drawroundrect=$(uci get oled.@oled[0].drawroundrect)
|
||||
fillroundrect=$(uci get oled.@oled[0].fillroundrect)
|
||||
drawtriangle=$(uci get oled.@oled[0].drawtriangle)
|
||||
filltriangle=$(uci get oled.@oled[0].filltriangle)
|
||||
displaybitmap=$(uci get oled.@oled[0].displaybitmap)
|
||||
displayinvertnormal=$(uci get oled.@oled[0].displayinvertnormal)
|
||||
drawbitmapeg=$(uci get oled.@oled[0].drawbitmapeg)
|
||||
scroll=$(uci get oled.@oled[0].scroll)
|
||||
text=$(uci get oled.@oled[0].text)
|
||||
netsource=$(uci get oled.@oled[0].netsource)
|
||||
|
||||
|
||||
kill -9 $(pgrep /usr/bin/oled)
|
||||
kill -9 $(pgrep -f /usr/sbin/netspeed)
|
||||
|
||||
if [ ${netspeed} -eq 1 ]; then
|
||||
nohup /usr/sbin/netspeed ${netsource} >/dev/null 2>&1 &
|
||||
else
|
||||
kill -9 $(pgrep -f /usr/sbin/netspeed)
|
||||
rm -f /tmp/netspeed
|
||||
fi
|
||||
nohup ${PROG} ${date} ${lanip} ${cputemp} ${cpufreq} ${netspeed} ${time} ${drawline} ${drawrect} ${fillrect} ${drawcircle} ${drawroundrect} ${fillroundrect} ${drawtriangle} ${filltriangle} ${displaybitmap} ${displayinvertnormal} ${drawbitmapeg} ${scroll} "${text}" "${netsource}" 0 > /dev/null 2>&1 &
|
||||
else
|
||||
stop
|
||||
fi
|
||||
|
||||
else
|
||||
if [ $enabled -eq 1 ]; then
|
||||
start
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
boot(){
|
||||
start
|
||||
}
|
11
luci-app-oled/root/etc/uci-defaults/oled
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@oled[-1]
|
||||
add ucitrack oled
|
||||
set ucitrack.@oled[-1].init=oled
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
20
luci-app-oled/root/usr/sbin/netspeed
Executable file
@ -0,0 +1,20 @@
|
||||
#!/bin/ash
|
||||
IF=$1
|
||||
if [ -z "$IF" ]; then
|
||||
IF=`ls -1 /sys/class/net/ | head -1`
|
||||
fi
|
||||
RXPREV=-1
|
||||
TXPREV=-1
|
||||
echo "Listening $IF..."
|
||||
while [ 1 == 1 ] ; do
|
||||
RX=`cat /sys/class/net/${IF}/statistics/rx_bytes`
|
||||
TX=`cat /sys/class/net/${IF}/statistics/tx_bytes`
|
||||
if [ $RXPREV -ne -1 ] ; then
|
||||
let BWRX=$RX-$RXPREV
|
||||
let BWTX=$TX-$TXPREV
|
||||
echo "$BWRX $BWTX">/tmp/netspeed
|
||||
fi
|
||||
RXPREV=$RX
|
||||
TXPREV=$TX
|
||||
sleep 1
|
||||
done
|
11
luci-app-oled/root/usr/share/rpcd/acl.d/luci-app-oled.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-oled": {
|
||||
"description": "Grant UCI access for luci-app-oled",
|
||||
"read": {
|
||||
"uci": [ "oled" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "oled" ]
|
||||
}
|
||||
}
|
||||
}
|
232
luci-app-oled/src/Example_Code/Main.c
Normal file
@ -0,0 +1,232 @@
|
||||
/*
|
||||
* Main.c
|
||||
*
|
||||
* Created on : Sep 6, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Description : Example usage of the SSD1306 Driver API's
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/* Lib Includes */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
|
||||
/* Header Files */
|
||||
#include "I2C.h"
|
||||
#include "SSD1306_OLED.h"
|
||||
#include "example_app.h"
|
||||
|
||||
/* Oh Compiler-Please leave me as is */
|
||||
volatile unsigned char flag = 0;
|
||||
|
||||
/* Alarm Signal Handler */
|
||||
void ALARMhandler(int sig)
|
||||
{
|
||||
/* Set flag */
|
||||
flag = 5;
|
||||
}
|
||||
|
||||
void BreakDeal(int sig)
|
||||
{
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
exit(0);
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
int date=atoi(argv[1]);
|
||||
int lanip=atoi(argv[2]);
|
||||
int cputemp=atoi(argv[3]);
|
||||
int cpufreq=atoi(argv[4]);
|
||||
int netspeed=atoi(argv[5]);
|
||||
int time=atoi(argv[6]);
|
||||
int drawline=atoi(argv[7]);
|
||||
int drawrect=atoi(argv[8]);
|
||||
int fillrect=atoi(argv[9]);
|
||||
int drawcircle=atoi(argv[10]);
|
||||
int drawroundcircle=atoi(argv[11]);
|
||||
int fillroundcircle=atoi(argv[12]);
|
||||
int drawtriangle=atoi(argv[13]);
|
||||
int filltriangle=atoi(argv[14]);
|
||||
int displaybitmap=atoi(argv[15]);
|
||||
int displayinvertnormal=atoi(argv[16]);
|
||||
int drawbitmapeg=atoi(argv[17]);
|
||||
int scroll=atoi(argv[18]);
|
||||
char *text=argv[19];
|
||||
char *eth = argv[20];
|
||||
int needinit=atoi(argv[21]);
|
||||
|
||||
|
||||
/* Initialize I2C bus and connect to the I2C Device */
|
||||
if(init_i2c_dev(I2C_DEV0_PATH, SSD1306_OLED_ADDR) == 0)
|
||||
{
|
||||
printf("(Main)i2c-2: Bus Connected to SSD1306\r\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
printf("(Main)i2c-2: OOPS! Something Went Wrong\r\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* Register the Alarm Handler */
|
||||
signal(SIGALRM, ALARMhandler);
|
||||
signal(SIGINT, BreakDeal);
|
||||
//signal(SIGTERM, BreakDeal);
|
||||
/* Run SDD1306 Initialization Sequence */
|
||||
if (needinit==1) {display_Init_seq();}
|
||||
|
||||
/* Clear display */
|
||||
clearDisplay();
|
||||
|
||||
// draw a single pixel
|
||||
// drawPixel(0, 1, WHITE);
|
||||
// Display();
|
||||
// usleep(1000000);
|
||||
// clearDisplay();
|
||||
|
||||
// draw many lines
|
||||
while(1){
|
||||
|
||||
if(scroll){
|
||||
testscrolltext(text);
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
if(drawline){
|
||||
testdrawline();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// draw rectangles
|
||||
if(drawrect){
|
||||
testdrawrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// draw multiple rectangles
|
||||
if(fillrect){
|
||||
testfillrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// draw mulitple circles
|
||||
if(drawcircle){
|
||||
testdrawcircle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// draw a white circle, 10 pixel radius
|
||||
if(drawroundcircle){
|
||||
testdrawroundrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
|
||||
// Fill the round rectangle
|
||||
if(fillroundcircle){
|
||||
testfillroundrect();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// Draw triangles
|
||||
if(drawtriangle){
|
||||
testdrawtriangle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
// Fill triangles
|
||||
if(filltriangle){
|
||||
testfilltriangle();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
|
||||
// Display miniature bitmap
|
||||
if(displaybitmap){
|
||||
display_bitmap();
|
||||
Display();
|
||||
usleep(1000000);
|
||||
};
|
||||
// Display Inverted image and normalize it back
|
||||
if(displayinvertnormal){
|
||||
display_invert_normal();
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
|
||||
}
|
||||
|
||||
// Generate Signal after 20 Seconds
|
||||
|
||||
// draw a bitmap icon and 'animate' movement
|
||||
if(drawbitmapeg){
|
||||
alarm(10);
|
||||
flag=0;
|
||||
testdrawbitmap_eg();
|
||||
clearDisplay();
|
||||
usleep(1000000);
|
||||
Display();
|
||||
}
|
||||
|
||||
|
||||
//setCursor(0,0);
|
||||
setTextColor(WHITE);
|
||||
// info display
|
||||
int sum = date+lanip+cpufreq+cputemp+netspeed;
|
||||
if (sum == 0) {clearDisplay(); return 0;}
|
||||
for(int i = 1; i < time; i++){
|
||||
if (sum == 1){//only one item for display
|
||||
if (date) testdate(CENTER, 8);
|
||||
if (lanip) testlanip(CENTER, 8);
|
||||
if (cpufreq) testcpufreq(CENTER, 8);
|
||||
if (cputemp) testcputemp(CENTER, 8);
|
||||
if (netspeed) testnetspeed(SPLIT,0);
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}else if (sum == 2){//two items for display
|
||||
if(date) {testdate(CENTER, 16*(date-1));}
|
||||
if(lanip) {testlanip(CENTER, 16*(date+lanip-1));}
|
||||
if(cpufreq) {testcpufreq(CENTER, 16*(date+lanip+cpufreq-1));}
|
||||
if(cputemp) {testcputemp(CENTER, 16*(date+lanip+cpufreq+cputemp-1));}
|
||||
if(netspeed) {testnetspeed(MERGE, 16*(date+lanip+cpufreq+cputemp+netspeed-1));}
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
else{//more than two items for display
|
||||
if(date) {testdate(FULL, 8*(date-1));}
|
||||
if(lanip) {testlanip(FULL, 8*(date+lanip-1));}
|
||||
if(cpufreq && cputemp) {
|
||||
testcpu(8*(date+lanip));
|
||||
if(netspeed) {testnetspeed(FULL, 8*(date+lanip+1+netspeed-1));}
|
||||
}
|
||||
else{
|
||||
if(cpufreq) {testcpufreq(FULL, 8*(date+lanip+cpufreq-1));}
|
||||
if(cputemp) {testcputemp(FULL, 8*(date+lanip+cpufreq+cputemp-1));}
|
||||
if(netspeed) {testnetspeed(FULL, 8*(date+lanip+cpufreq+cputemp+netspeed-1));}
|
||||
}
|
||||
|
||||
Display();
|
||||
usleep(1000000);
|
||||
clearDisplay();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
650
luci-app-oled/src/Example_Code/example_app.c
Normal file
@ -0,0 +1,650 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* example_app.c
|
||||
*
|
||||
* Created on : Sep 6, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/* Lib Includes */
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
#include "SSD1306_OLED.h"
|
||||
#include "example_app.h"
|
||||
|
||||
#define BUFMAX SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT
|
||||
|
||||
/* MACRO's */
|
||||
#define LOGO16_GLCD_HEIGHT 16
|
||||
#define LOGO16_GLCD_WIDTH 16
|
||||
#define NUMFLAKES 10
|
||||
#define XPOS 0
|
||||
#define YPOS 1
|
||||
#define DELTAY 2
|
||||
|
||||
|
||||
|
||||
#define TIMESIZE 64
|
||||
//temperature
|
||||
#define TEMPPATH "/sys/class/thermal/thermal_zone0/temp"
|
||||
#define TEMPSIZE 5
|
||||
//cpu
|
||||
#define FREQSIZE 8
|
||||
#define FREQPATH "cat /sys/devices/system/cpu/cpu[04]/cpufreq/cpuinfo_cur_freq"
|
||||
//ip
|
||||
#define IPPATH "ifconfig br-lan|grep 'inet addr:'|cut -d: -f2|awk '{print $1}'"
|
||||
#define IPSIZE 20
|
||||
//netspeed
|
||||
#define NETPATH "cat /tmp/netspeed"
|
||||
|
||||
/* Extern volatile */
|
||||
extern volatile unsigned char flag;
|
||||
|
||||
/* Bit Map - Taken from Adafruit SSD1306 OLED Library */
|
||||
static const unsigned char logo16_glcd_bmp[] =
|
||||
{
|
||||
0b00000000, 0b11000000,
|
||||
0b00000001, 0b11000000,
|
||||
0b00000001, 0b11000000,
|
||||
0b00000011, 0b11100000,
|
||||
0b11110011, 0b11100000,
|
||||
0b11111110, 0b11111000,
|
||||
0b01111110, 0b11111111,
|
||||
0b00110011, 0b10011111,
|
||||
0b00011111, 0b11111100,
|
||||
0b00001101, 0b01110000,
|
||||
0b00011011, 0b10100000,
|
||||
0b00111111, 0b11100000,
|
||||
0b00111111, 0b11110000,
|
||||
0b01111100, 0b11110000,
|
||||
0b01110000, 0b01110000,
|
||||
0b00000000, 0b00110000
|
||||
};
|
||||
|
||||
FILE *fp;
|
||||
char content_buff[BUFMAX];
|
||||
char buf[BUFMAX];
|
||||
int display_offset =7;
|
||||
/* draw many lines */
|
||||
void testdrawline()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4)
|
||||
{
|
||||
drawLine(0, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=4)
|
||||
{
|
||||
drawLine(0, 0, SSD1306_LCDWIDTH-1, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4)
|
||||
{
|
||||
drawLine(0, SSD1306_LCDHEIGHT-1, i, 0, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=SSD1306_LCDHEIGHT-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(0, SSD1306_LCDHEIGHT-1, SSD1306_LCDWIDTH-1, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=SSD1306_LCDWIDTH-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, i, 0, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=SSD1306_LCDHEIGHT-1; i>=0; i-=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, SSD1306_LCDHEIGHT-1, 0, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
|
||||
clearDisplay();
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=4)
|
||||
{
|
||||
drawLine(SSD1306_LCDWIDTH-1, 0, 0, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
for (i=0; i<SSD1306_LCDWIDTH; i+=4) {
|
||||
drawLine(SSD1306_LCDWIDTH-1, 0, i, SSD1306_LCDHEIGHT-1, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
usleep(250000);
|
||||
}
|
||||
|
||||
/* draw rectangles */
|
||||
void testdrawrect()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2; i+=2)
|
||||
{
|
||||
drawRect(i, i,SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* draw multiple rectangles */
|
||||
void testfillrect()
|
||||
{
|
||||
unsigned char color = 1;
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2; i+=3)
|
||||
{
|
||||
// alternate colors
|
||||
fillRect(i, i, SSD1306_LCDWIDTH-i*2, SSD1306_LCDHEIGHT-i*2, color%2);
|
||||
Display();
|
||||
usleep(1000);
|
||||
color++;
|
||||
}
|
||||
}
|
||||
|
||||
/* draw mulitple circles */
|
||||
void testdrawcircle()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT; i+=2)
|
||||
{
|
||||
drawCircle(SSD1306_LCDWIDTH/2,SSD1306_LCDHEIGHT/2, i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/*draw a white circle, 10 pixel radius */
|
||||
void testdrawroundrect()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2-2; i+=2) {
|
||||
drawRoundRect(i, i,SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, SSD1306_LCDHEIGHT/4, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill the round rectangle */
|
||||
void testfillroundrect()
|
||||
{
|
||||
short color = WHITE,i = 0;
|
||||
for (i=0; i<SSD1306_LCDHEIGHT/2-2; i+=2)
|
||||
{
|
||||
fillRoundRect(i, i, SSD1306_LCDWIDTH-2*i, SSD1306_LCDHEIGHT-2*i, SSD1306_LCDHEIGHT/4, color);
|
||||
if (color == WHITE)
|
||||
color = BLACK;
|
||||
else
|
||||
color = WHITE;
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw triangles */
|
||||
void testdrawtriangle()
|
||||
{
|
||||
short i = 0;
|
||||
for (i=0; i<MIN(SSD1306_LCDWIDTH,SSD1306_LCDHEIGHT)/2; i+=5)
|
||||
{
|
||||
drawTriangle(SSD1306_LCDWIDTH/2, SSD1306_LCDHEIGHT/2-i,
|
||||
SSD1306_LCDWIDTH/2-i,SSD1306_LCDHEIGHT /2+i,
|
||||
SSD1306_LCDWIDTH/2+i, SSD1306_LCDHEIGHT/2+i, WHITE);
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Fill triangles */
|
||||
void testfilltriangle()
|
||||
{
|
||||
unsigned char color = WHITE;
|
||||
short i = 0;
|
||||
for (i=MIN(SSD1306_LCDWIDTH,SSD1306_LCDHEIGHT)/2; i>0; i-=5)
|
||||
{
|
||||
fillTriangle(SSD1306_LCDWIDTH/2, SSD1306_LCDHEIGHT/2-i,
|
||||
SSD1306_LCDWIDTH/2-i, SSD1306_LCDHEIGHT/2+i,
|
||||
SSD1306_LCDWIDTH/2+i, SSD1306_LCDHEIGHT/2+i, WHITE);
|
||||
if (color == WHITE)
|
||||
color = BLACK;
|
||||
else
|
||||
color = WHITE;
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
}
|
||||
|
||||
/* Display a bunch of characters and emoticons */
|
||||
void testdrawchar()
|
||||
{
|
||||
unsigned char i = 0;
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(0,0);
|
||||
|
||||
for (i=0; i < 168; i++)
|
||||
{
|
||||
if (i == '\n')
|
||||
continue;
|
||||
oled_write(i);
|
||||
if ((i > 0) && (i % 21 == 0))
|
||||
println();
|
||||
}
|
||||
Display();
|
||||
usleep(1000);
|
||||
}
|
||||
|
||||
/* Display "scroll" and scroll around */
|
||||
void testscrolltext(char* str)
|
||||
{
|
||||
setTextSize(2);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,8);
|
||||
sprintf(buf,"%s",str);
|
||||
print_strln(buf);
|
||||
Display();
|
||||
usleep(1000);
|
||||
startscrollright(0x00, 0x0F);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
usleep(1000000);
|
||||
startscrollleft(0x00, 0x0F);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
usleep(1000000);
|
||||
startscrolldiagright(0x00, 0x07);
|
||||
usleep(5000000);
|
||||
startscrolldiagleft(0x00, 0x07);
|
||||
usleep(5000000);
|
||||
stopscroll();
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Display Texts */
|
||||
void display_texts()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,0);
|
||||
print_str("HELLO FELLAS!");
|
||||
println();
|
||||
printFloat_ln(3.141592, 4); //Print 4 No's after the decimal Pt.
|
||||
printNumber_L_ln(-1234, DEC);
|
||||
printNumber_UC_ln(170, BIN);
|
||||
setTextSize(2);
|
||||
setTextColor(WHITE);
|
||||
print_str("0x");
|
||||
printNumber_UL_ln(0xDEADBEEF, HEX);
|
||||
}
|
||||
|
||||
/* Display miniature bitmap */
|
||||
void display_bitmap()
|
||||
{
|
||||
drawBitmap(30, 16, logo16_glcd_bmp, 16, 16, 1);
|
||||
}
|
||||
|
||||
/* Invert Display and Normalize it */
|
||||
void display_invert_normal()
|
||||
{
|
||||
invertDisplay(SSD1306_INVERT_DISPLAY);
|
||||
usleep(1000000);
|
||||
invertDisplay(SSD1306_NORMALIZE_DISPLAY);
|
||||
usleep(1000000);
|
||||
}
|
||||
|
||||
/* Draw a bitmap and 'animate' movement */
|
||||
void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h)
|
||||
{
|
||||
unsigned char icons[NUMFLAKES][3], f = 0;
|
||||
|
||||
// initialize
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
icons[f][XPOS] = rand() % SSD1306_LCDWIDTH;
|
||||
icons[f][YPOS] = 0;
|
||||
icons[f][DELTAY] = (rand() % 5) + 1;
|
||||
|
||||
/* Looks kinna ugly to me - Un-Comment if you need it */
|
||||
//print_str("x: ");
|
||||
//printNumber_UC(icons[f][XPOS], DEC);
|
||||
//print_str("y: ");
|
||||
//printNumber_UC(icons[f][YPOS], DEC);
|
||||
//print_str("dy: ");
|
||||
//printNumber_UC(icons[f][DELTAY], DEC);
|
||||
}
|
||||
|
||||
while (flag != 5)
|
||||
{
|
||||
// draw each icon
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, WHITE);
|
||||
}
|
||||
Display();
|
||||
usleep(200000);
|
||||
|
||||
// then erase it + move it
|
||||
for (f=0; f< NUMFLAKES; f++)
|
||||
{
|
||||
drawBitmap(icons[f][XPOS], icons[f][YPOS], bitmap, w, h, BLACK);
|
||||
|
||||
// move it
|
||||
icons[f][YPOS] += icons[f][DELTAY];
|
||||
|
||||
// if its gone, reinit
|
||||
if (icons[f][YPOS] > SSD1306_LCDHEIGHT)
|
||||
{
|
||||
icons[f][XPOS] = rand() % SSD1306_LCDWIDTH;
|
||||
icons[f][YPOS] = 0;
|
||||
icons[f][DELTAY] = (rand() % 5) + 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Draw bitmap and animate */
|
||||
void testdrawbitmap_eg()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(10,0);
|
||||
testdrawbitmap(logo16_glcd_bmp, LOGO16_GLCD_HEIGHT, LOGO16_GLCD_WIDTH);
|
||||
}
|
||||
|
||||
/* Intro */
|
||||
void deeplyembedded_credits()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(1,0);
|
||||
print_strln("deeplyembedded.org");
|
||||
println();
|
||||
print_strln("Author:Vinay Divakar");
|
||||
println();
|
||||
println();
|
||||
print_strln("THANK YOU");
|
||||
}
|
||||
|
||||
|
||||
void testdate(int mode, int y)
|
||||
{
|
||||
time_t rawtime;
|
||||
time_t curtime;
|
||||
uint8_t timebuff[TIMESIZE];
|
||||
curtime = time(NULL);
|
||||
time(&rawtime);
|
||||
switch (mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
strftime(timebuff,80,"%H:%M",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
setCursor((127-strlen(buf)*11)/2-4, y);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
strftime(timebuff,80,"%Y-%m-%d %H:%M:%S",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
|
||||
void testlanip(int mode, int y)
|
||||
{
|
||||
setTextSize(1);
|
||||
if((fp=popen(IPPATH,"r"))!=NULL)
|
||||
{
|
||||
fscanf(fp,"%s",content_buff);
|
||||
fclose(fp);
|
||||
//ipbuff[strlen(ipbuff)-1]=32;
|
||||
switch(mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"%s",content_buff);
|
||||
setCursor((127-strlen(buf)*6)/2, y+4);
|
||||
break;
|
||||
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"IP:%s",content_buff);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void testcputemp(int mode, int y)
|
||||
{
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
switch (mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
sprintf(buf, "%.2f",atoi(content_buff)/100.0);
|
||||
setCursor((127-(strlen(buf)+2)*11)/2-4, y);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-16, getCursorY()+3, 2, WHITE);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"CPU TEMP:%.2f",atoi(content_buff)/100.0);
|
||||
setCursor(display_offset, y);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
void testcpufreq(int mode, int y)
|
||||
{
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
switch(mode)
|
||||
{
|
||||
case CENTER:
|
||||
setTextSize(2);
|
||||
sprintf(buf,"%4dMHz",atoi(content_buff)/1000);
|
||||
setCursor((127-strlen(buf)*11)/2-4, y);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
sprintf(buf,"CPU FREQ:%4dMHz",atoi(content_buff)/1000);
|
||||
setCursor(display_offset, y);
|
||||
}
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void testnetspeed(int mode, int y)
|
||||
{
|
||||
int rx,tx;
|
||||
if((fp=popen(NETPATH,"r")) != NULL)
|
||||
{
|
||||
fscanf(fp,"%d %d", &rx, &tx);
|
||||
fclose(fp);
|
||||
rx = rx;
|
||||
tx = tx;
|
||||
switch(mode)
|
||||
{
|
||||
case SPLIT:
|
||||
setTextSize(2);
|
||||
if (tx < 1000) sprintf(buf, "%03dB", tx);
|
||||
else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000);
|
||||
else sprintf(buf, "%03dK", tx/1000);
|
||||
setCursor((127-(strlen(buf)+1)*11)/2,0);
|
||||
oled_write(24);
|
||||
print_str(buf);
|
||||
|
||||
if (rx < 1000) sprintf(buf, "%03dB", rx);
|
||||
else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000);
|
||||
else sprintf(buf, "%03dK", rx/1000);
|
||||
setCursor((127-(strlen(buf)+1)*11)/2,16);
|
||||
oled_write(25);
|
||||
print_str(buf);
|
||||
break;
|
||||
case MERGE:
|
||||
setTextSize(1);
|
||||
if (tx < 1000) sprintf(buf, "%03dB ", tx);
|
||||
else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000);
|
||||
else sprintf(buf, "%03dK ", tx/1000);
|
||||
setCursor((127-(2*strlen(buf)-1)*6)/2-4, y+4);
|
||||
oled_write(24);
|
||||
print_str(buf);
|
||||
|
||||
if (rx < 1000) sprintf(buf, "%03dB", rx);
|
||||
else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000);
|
||||
else sprintf(buf, "%03dK", rx/1000);
|
||||
oled_write(25);
|
||||
print_str(buf);
|
||||
break;
|
||||
case FULL:
|
||||
setTextSize(1);
|
||||
setCursor(display_offset, y);
|
||||
oled_write(24);
|
||||
if (tx < 1000) sprintf(buf, "%03dB ", tx);
|
||||
else if (tx > 1000000) sprintf(buf, "%03dM", tx/1000000);
|
||||
else sprintf(buf, "%03dK ", tx/1000);
|
||||
print_str(buf);
|
||||
|
||||
oled_write(25);
|
||||
if (rx < 1000) sprintf(buf, "%03dB", rx);
|
||||
else if (rx > 1000000) sprintf(buf, "%03dM", rx/1000000);
|
||||
else sprintf(buf, "%03dK", rx/1000);
|
||||
print_str(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
void testcpu(int y)
|
||||
{
|
||||
//freq
|
||||
setTextSize(1);
|
||||
setCursor(display_offset, y);
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU:%4dMHz ", atoi(content_buff)/1000);
|
||||
print_str(buf);
|
||||
}
|
||||
|
||||
|
||||
//temp
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf, "%.2f",atoi(content_buff)/100.0);
|
||||
print_str(buf);
|
||||
oled_write(0);
|
||||
oled_write(67);
|
||||
drawCircle(getCursorX()-8, getCursorY()+1, 1, WHITE);
|
||||
}
|
||||
}
|
||||
|
||||
void testprintinfo()
|
||||
{
|
||||
setTextSize(1);
|
||||
setTextColor(WHITE);
|
||||
setCursor(0,0);
|
||||
//DATE
|
||||
|
||||
time_t rawtime;
|
||||
time_t curtime;
|
||||
uint8_t timebuff[TIMESIZE];
|
||||
curtime = time(NULL);
|
||||
time(&rawtime);
|
||||
strftime(timebuff,80,"%Y-%m-%d_%w %H:%M:%S",localtime(&rawtime));
|
||||
sprintf(buf,"%s",timebuff);
|
||||
print_strln(buf);
|
||||
|
||||
//br-lan ip
|
||||
if((fp=popen(IPPATH,"r"))!=NULL)
|
||||
{
|
||||
fscanf(fp,"%s",content_buff);
|
||||
fclose(fp);
|
||||
//ipbuff[strlen(ipbuff)-1]=32;
|
||||
sprintf(buf,"IP:%s",content_buff);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
//CPU temp
|
||||
if((fp=popen(FREQPATH,"r")) != NULL)
|
||||
{
|
||||
fgets(content_buff,FREQSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU freq:%d MHz ",atoi(content_buff)/1000);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
//cpu freq
|
||||
if((fp=fopen(TEMPPATH,"r"))!=NULL)
|
||||
{
|
||||
fgets(content_buff,TEMPSIZE,fp);
|
||||
fclose(fp);
|
||||
sprintf(buf,"CPU temp:%.2f C",atoi(content_buff)/100.0);
|
||||
print_strln(buf);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
30
luci-app-oled/src/Example_Code/example_app.h
Normal file
@ -0,0 +1,30 @@
|
||||
#define CENTER 0 //single item display
|
||||
#define SPLIT 1 //two items
|
||||
#define MERGE 2
|
||||
#define FULL 3
|
||||
|
||||
void testdrawline();
|
||||
void testdrawrect();
|
||||
void testfillrect();
|
||||
void testdrawcircle();
|
||||
void testdrawroundrect();
|
||||
void testfillroundrect();
|
||||
void testdrawtriangle();
|
||||
void testfilltriangle();
|
||||
void testdrawchar();
|
||||
void testscrolltext(char *str);
|
||||
void display_texts();
|
||||
void display_bitmap();
|
||||
void display_invert_normal();
|
||||
void testdrawbitmap(const unsigned char *bitmap, unsigned char w, unsigned char h);
|
||||
void testdrawbitmap_eg();
|
||||
void deeplyembedded_credits();
|
||||
void testprintinfo();
|
||||
void testdate(int mode, int y);
|
||||
void testlanip(int mode, int y);
|
||||
void testcpufreq(int mode, int y);
|
||||
void testcputemp(int mode, int y);
|
||||
void testnetspeed(int mode, int y);
|
||||
void testcpu(int y);
|
||||
|
||||
|
281
luci-app-oled/src/I2C_Library/I2C.c
Normal file
@ -0,0 +1,281 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* I2C.c
|
||||
*
|
||||
* Created on : September 19, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Description : This is an I2C Library for the BeagleBone that consists of the API's to support the standard
|
||||
* I2C operations.
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
/*Libs Includes*/
|
||||
#include<stdio.h>
|
||||
#include<fcntl.h>
|
||||
#include<sys/ioctl.h>
|
||||
#include <unistd.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
// heuristic to guess what version of i2c-dev.h we have:
|
||||
// the one installed with `apt-get install libi2c-dev`
|
||||
// would conflict with linux/i2c.h, while the stock
|
||||
// one requires linus/i2c.h
|
||||
#ifndef I2C_SMBUS_BLOCK_MAX
|
||||
// If this is not defined, we have the "stock" i2c-dev.h
|
||||
// so we include linux/i2c.h
|
||||
#include <linux/i2c.h>
|
||||
typedef unsigned char i2c_char_t;
|
||||
#else
|
||||
typedef char i2c_char_t;
|
||||
#endif
|
||||
|
||||
/* Header Files */
|
||||
#include "I2C.h"
|
||||
|
||||
|
||||
/* Exposed objects for i2c-x */
|
||||
I2C_DeviceT I2C_DEV_2;
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Open_device
|
||||
* Description : Opens the I2C device to use
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @i2c_dev_path: Path to the I2C device
|
||||
* @fd: Variable to store the file handler
|
||||
****************************************************************/
|
||||
int Open_device(char *i2c_dev_path, int *fd)
|
||||
{
|
||||
if((*fd = open(i2c_dev_path, O_RDWR))<0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Close_device
|
||||
* Description : Closes the I2C device in use
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params : @fd: file descriptor
|
||||
****************************************************************/
|
||||
int Close_device(int fd)
|
||||
{
|
||||
if(close(fd) == -1)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : Set_slave_addr
|
||||
* Description : Connect to the Slave device
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @slave_addr: Address of the slave device to
|
||||
* talk to.
|
||||
****************************************************************/
|
||||
int Set_slave_addr(int fd, unsigned char slave_addr)
|
||||
{
|
||||
if(ioctl(fd, I2C_SLAVE, slave_addr) < 0)
|
||||
return -1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_write
|
||||
* Description : Write a byte on SDA
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @data: data to write on SDA
|
||||
****************************************************************/
|
||||
int i2c_write(int fd, unsigned char data)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = write(fd, &data, I2C_ONE_BYTE);
|
||||
if((ret == -1) || (ret != 1))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read
|
||||
* Description : Read a byte on SDA
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @read_data: Points to the variable that stores
|
||||
* the read data byte
|
||||
****************************************************************/
|
||||
int i2c_read(int fd, unsigned char *read_data)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = read(fd, &read_data, I2C_ONE_BYTE);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read_register
|
||||
* Description : Read a single register of the slave device
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @read_addr: Register address to be read
|
||||
* @read_data: Points to the variable that stores
|
||||
* the read data byte
|
||||
****************************************************************/
|
||||
int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data)
|
||||
{
|
||||
int ret = 0;
|
||||
if(i2c_write(fd, read_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to write |");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, &read_data, I2C_ONE_BYTE);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_read_registers
|
||||
* Description : Read a multiple registers on the slave device
|
||||
* from starting address
|
||||
* Returns : No. of bytes read on success, -1 on failure
|
||||
* Params @fd: File descriptor
|
||||
* @num: Number of registers/bytes to read from.
|
||||
* @starting_addr: Starting address to read from
|
||||
* @buff_Ptr: Buffer to store the read bytes
|
||||
****************************************************************/
|
||||
int i2c_read_registers(int fd, int num, unsigned char starting_addr,
|
||||
unsigned char *buff_Ptr)
|
||||
{
|
||||
int ret = 0;
|
||||
if(i2c_write(fd, starting_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to write |");
|
||||
return -1;
|
||||
}
|
||||
ret = read(fd, buff_Ptr, num);
|
||||
if(ret == -1)
|
||||
perror("I2C: Failed to read |");
|
||||
if(ret == 0)
|
||||
perror("I2C: End of FILE |");
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_multiple_writes
|
||||
* Description : Write multiple bytes on SDA
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: file descriptor
|
||||
* @num: No. of bytes to write
|
||||
* @Ptr_buff: Pointer to the buffer containing the
|
||||
* bytes to be written on the SDA
|
||||
****************************************************************/
|
||||
int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff)
|
||||
{
|
||||
int ret = 0;
|
||||
ret = write(fd, Ptr_buff, num);
|
||||
if((ret == -1) || (ret != num))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : i2c_write_register
|
||||
* Description : Write a control byte or byte to a register
|
||||
* Returns : No. of bytes written on success, -1 on failure
|
||||
* Params @fd: file descriptor
|
||||
* @reg_addr_or_cntrl: Control byte or Register
|
||||
* address to be written
|
||||
* @val: Command or value to be written in the
|
||||
* addressed register
|
||||
****************************************************************/
|
||||
int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val)
|
||||
{
|
||||
unsigned char buff[2];
|
||||
int ret = 0;
|
||||
buff[0] = reg_addr_or_cntrl;
|
||||
buff[1] = val;
|
||||
ret = write(fd, buff, I2C_TWO_BYTES);
|
||||
if((ret == -1) || (ret != I2C_TWO_BYTES))
|
||||
return -1;
|
||||
else
|
||||
return(ret);
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : config_i2c_struct
|
||||
* Description : Initialize the I2C device structure
|
||||
* Returns : NONE
|
||||
* Params @i2c_dev_path: Device path
|
||||
* @slave_addr: Slave device address
|
||||
* @i2c_dev: Pointer to the device structure
|
||||
****************************************************************/
|
||||
void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev)
|
||||
{
|
||||
i2c_dev->i2c_dev_path = i2c_dev_path;
|
||||
i2c_dev->fd_i2c = 0;
|
||||
i2c_dev->i2c_slave_addr = slave_addr;
|
||||
}
|
||||
|
||||
|
||||
/****************************************************************
|
||||
* Function Name : init_i2c_dev
|
||||
* Description : Connect the i2c bus to the slave device
|
||||
* Returns : 0 on success, -1 on failure
|
||||
* Params @i2c_path: the path to the device
|
||||
* @slave_addr: Slave device address
|
||||
****************************************************************/
|
||||
int init_i2c_dev(const char* i2c_path, unsigned char slave_address)
|
||||
{
|
||||
config_i2c_struct((char*)i2c_path, slave_address, &I2C_DEV_2);
|
||||
if(Open_device(I2C_DEV_2.i2c_dev_path, &I2C_DEV_2.fd_i2c) == -1)
|
||||
{
|
||||
perror("I2C: Failed to open device |");
|
||||
return -1;
|
||||
}
|
||||
if(Set_slave_addr(I2C_DEV_2.fd_i2c, I2C_DEV_2.i2c_slave_addr) == -1)
|
||||
{
|
||||
perror("I2C: Failed to connect to slave device |");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
69
luci-app-oled/src/I2C_Library/I2C.h
Normal file
@ -0,0 +1,69 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* I2C.h
|
||||
*
|
||||
* Created on : Sep 4, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
#ifndef I2C_H_
|
||||
#define I2C_H_
|
||||
|
||||
#include<stdint.h>
|
||||
|
||||
/* No. of bytes per transaction */
|
||||
#define I2C_ONE_BYTE 1
|
||||
#define I2C_TWO_BYTES 2
|
||||
#define I2C_THREE_BYTES 3
|
||||
|
||||
/*Definitions specific to i2c-x */
|
||||
#define I2C_DEV0_PATH "/dev/i2c-0"
|
||||
#define I2C_DEV1_PATH "/dev/i2c-1"
|
||||
#define I2C_DEV2_PATH "/dev/i2c-2"
|
||||
|
||||
/*I2C device configuration structure*/
|
||||
typedef struct{
|
||||
char* i2c_dev_path;
|
||||
int fd_i2c;
|
||||
unsigned char i2c_slave_addr;
|
||||
}I2C_DeviceT, *I2C_DevicePtr;
|
||||
|
||||
/* Exposed Generic I2C Functions */
|
||||
extern int Open_device(char *i2c_dev_path, int *fd);
|
||||
extern int Close_device(int fd);
|
||||
extern int Set_slave_addr(int fd, unsigned char slave_addr);
|
||||
extern int i2c_write(int fd, unsigned char data);
|
||||
extern int i2c_read(int fd, unsigned char *read_data);
|
||||
extern int i2c_read_register(int fd, unsigned char read_addr, unsigned char *read_data);
|
||||
extern int i2c_read_registers(int fd, int num, unsigned char starting_addr,
|
||||
unsigned char *buff_Ptr);
|
||||
extern void config_i2c_struct(char *i2c_dev_path, unsigned char slave_addr, I2C_DevicePtr i2c_dev);
|
||||
extern int i2c_multiple_writes(int fd, int num, unsigned char *Ptr_buff);
|
||||
extern int i2c_write_register(int fd, unsigned char reg_addr_or_cntrl, unsigned char val);
|
||||
|
||||
/* Exposed I2C-x Specific Functions */
|
||||
extern int init_i2c_dev(const char* i2c_path, unsigned char slave_address);
|
||||
|
||||
#endif /* I2C_H_ */
|
21
luci-app-oled/src/LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
19
luci-app-oled/src/Makefile
Normal file
@ -0,0 +1,19 @@
|
||||
CC = gcc
|
||||
LD = gcc
|
||||
|
||||
SOURCES = SSD1306_OLED_Library/SSD1306_OLED.c Example_Code/Main.c Example_Code/example_app.c I2C_Library/I2C.c
|
||||
OBJS := $(SOURCES:.c=.o)
|
||||
CPPFLAGS := -I SSD1306_OLED_Library -I I2C_Library
|
||||
CFLAGS := -g
|
||||
|
||||
oled: $(OBJS)
|
||||
$(CC) $^ -o $@
|
||||
|
||||
clean:
|
||||
rm -rf oled $(OBJS)
|
||||
|
||||
compile: oled
|
||||
|
||||
install: compile
|
||||
mkdir -p $(DESTDIR)/usr/bin
|
||||
cp oled $(DESTDIR)/usr/bin/oled
|
21
luci-app-oled/src/README.md
Normal file
@ -0,0 +1,21 @@
|
||||
# SSD1306-OLED-display-driver-for-BeagleBone
|
||||
This is a SSD1306 OLED Display Library fully compatible with the BeagleBone.
|
||||
|
||||
The Library has 3 components:
|
||||
1. I2C component for enabling communication between the BeagleBone and display.
|
||||
2. Control component for sending I2C commands to configure and control the display.
|
||||
3. Graphics component for drawing geometrical figures, bitmaps, texts, characters, emoticons and numbers.
|
||||
|
||||
Author: Vinay Divakar
|
||||
|
||||
References:
|
||||
1. https://github.com/adafruit/Adafruit_SSD1306
|
||||
2. https://github.com/adafruit/Adafruit-GFX-Library
|
||||
|
||||
Youtube demo: https://youtu.be/sDKf6zW6Pyg
|
||||
|
||||
MIT license, check LICENSE file for more information
|
||||
|
||||
This Library is written in C. To use it, just include the I2C and SSD1306 Libraries in your project.
|
||||
|
||||
Enjoy :)
|
2713
luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.c
Normal file
202
luci-app-oled/src/SSD1306_OLED_Library/SSD1306_OLED.h
Normal file
@ -0,0 +1,202 @@
|
||||
/*
|
||||
* MIT License
|
||||
|
||||
Copyright (c) 2017 DeeplyEmbedded
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
|
||||
* SSD1306_OLED.h
|
||||
*
|
||||
* Created on : Sep 21, 2017
|
||||
* Author : Vinay Divakar
|
||||
* Website : www.deeplyembedded.org
|
||||
*/
|
||||
|
||||
#ifndef SSD1306_OLED_H_
|
||||
#define SSD1306_OLED_H_
|
||||
|
||||
/* Lib's */
|
||||
#include <stdbool.h>
|
||||
|
||||
/* Find Min and Max - MACROS */
|
||||
#define MIN(a,b) (((a)<(b))?(a):(b))
|
||||
#define MAX(a,b) (((a)>(b))?(a):(b))
|
||||
|
||||
/* I2C Address of SSD1306 */
|
||||
#define SSD1306_OLED_ADDR 0x3C
|
||||
#define DISPLAY_BUFF_SIZE (SSD1306_LCDWIDTH*SSD1306_LCDHEIGHT/8)
|
||||
|
||||
/* COLOR MACROS */
|
||||
#define WHITE 1
|
||||
#define BLACK 0
|
||||
#define INVERSE 2
|
||||
|
||||
/* Number output format */
|
||||
#define DEC 10
|
||||
#define HEX 16
|
||||
#define OCT 8
|
||||
#define BIN 2
|
||||
#define DEFAULT 0
|
||||
|
||||
/*D/C# bit is '0' indicating that following
|
||||
* byte is a command. '1' is for data
|
||||
*/
|
||||
#define SSD1306_CNTRL_CMD 0x00
|
||||
#define SSD1306_CNTRL_DATA 0x40
|
||||
|
||||
|
||||
/*-----------------------Enable the WxL of the Display ---------------------------*/
|
||||
//#define SSD1306_128_64
|
||||
#define SSD1306_128_32
|
||||
//#define SSD1306_96_16
|
||||
/*--------------------------------------------------------------------------------*/
|
||||
|
||||
/* LCD HxW i.e. 64x128 || WxL i.e. 128x64 */
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 64
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_LCDWIDTH 128
|
||||
#define SSD1306_LCDHEIGHT 32
|
||||
#endif
|
||||
#if defined SSD1306_96_16
|
||||
#define SSD1306_LCDWIDTH 96
|
||||
#define SSD1306_LCDHEIGHT 16
|
||||
#endif
|
||||
|
||||
/* SSD1306 Commands */
|
||||
#define SSD1306_DISPLAY_OFF 0xAE
|
||||
#define SSD1306_SET_DISP_CLK 0xD5
|
||||
#define SSD1306_SET_MULTIPLEX 0xA8
|
||||
#define SSD1306_SET_DISP_OFFSET 0xD3
|
||||
#define SSD1306_SET_DISP_START_LINE 0x40// | 0x00)
|
||||
#define SSD1306_CONFIG_CHARGE_PUMP 0x8D
|
||||
#define SSD1306_SET_MEM_ADDR_MODE 0x20
|
||||
#define SSD1306_SEG_REMAP (0xA0 | 0x01) //Rotate 180 Degrees
|
||||
#define SSD1306_SET_COMSCANDEC 0xC8
|
||||
#define SSD1306_SET_COMPINS 0xDA
|
||||
#define SSD1306_SET_CONTRAST 0x81
|
||||
#define SSD1306_SET_PRECHARGE 0xD9
|
||||
#define SSD1306_SET_VCOMDETECT 0xDB
|
||||
#define SSD1306_DISPLAYALLON_RESUME 0xA4
|
||||
#define SSD1306_NORMAL_DISPLAY 0xA6
|
||||
#define SSD1306_DISPLAYON 0xAF
|
||||
#define SSD1306_SET_COL_ADDR 0x21
|
||||
#define SSD1306_PAGEADDR 0x22
|
||||
#define SSD1306_INVERT_DISPLAY 0x01
|
||||
#define SSD1306_NORMALIZE_DISPLAY 0x00
|
||||
|
||||
/* SDD1306 Scroll Commands */
|
||||
#define SSD1306_SET_VERTICAL_SCROLL_AREA 0xA3
|
||||
#define SSD1306_ACTIVATE_SCROLL 0x2F
|
||||
#define SSD1306_DEACTIVATE_SCROLL 0x2E
|
||||
#define SSD1306_RIGHT_HORIZONTAL_SCROLL 0x26
|
||||
#define SSD1306_LEFT_HORIZONTAL_SCROLL 0x27
|
||||
#define SSD1306_VERTICAL_AND_RIGHT_HORIZONTAL_SCROLL 0x29
|
||||
#define SSD1306_VERTICAL_AND_LEFT_HORIZONTAL_SCROLL 0x2A
|
||||
#define SSD1306_INVERTDISPLAY 0xA7
|
||||
|
||||
/* SSD1306 Configuration Commands */
|
||||
#define SSD1306_DISPCLK_DIV 0x80
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_MULT_64 0x3F
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_MULT_64 0x1F
|
||||
#endif
|
||||
#define SSD1306_MULT_64 0x1F
|
||||
#define SSD1306_DISP_OFFSET_VAL 0x00
|
||||
#define SSD1306_COL_START_ADDR 0x00 //Reset to = 0
|
||||
#define SSD1306_COL_END_ADDR (SSD1306_LCDWIDTH - 1) //Reset to = 127
|
||||
#define SSD1306_PG_START_ADDR 0x00
|
||||
#define SSD1306_PG_END_ADDR 7
|
||||
#define SSD1306_CHARGE_PUMP_EN 0x14
|
||||
#if defined SSD1306_128_64
|
||||
#define SSD1306_CONFIG_COM_PINS 0x12
|
||||
#endif
|
||||
#if defined SSD1306_128_32
|
||||
#define SSD1306_CONFIG_COM_PINS 0x02
|
||||
#endif
|
||||
#define SSD1306_CONTRAST_VAL 0xCF //207
|
||||
#define SSD1306_PRECHARGE_VAL 0xF1
|
||||
#define SSD1306_VCOMH_VAL 0x40
|
||||
#define SSD1306_MULT_DAT (SSD1306_LCDHEIGHT - 1)
|
||||
#define SSD1306_HOR_MM 0x00
|
||||
|
||||
/*SSD1306 Display API's */
|
||||
extern void clearDisplay();
|
||||
extern void display_Init_seq();
|
||||
extern void Display();
|
||||
extern void Init_Col_PG_addrs(unsigned char col_start_addr, unsigned char col_end_addr,
|
||||
unsigned char pg_start_addr, unsigned char pg_end_addr);
|
||||
extern void setRotation(unsigned char x);
|
||||
extern void startscrollright(unsigned char start, unsigned char stop);
|
||||
extern void startscrollleft(unsigned char start, unsigned char stop);
|
||||
extern void startscrolldiagright(unsigned char start, unsigned char stop);
|
||||
extern void startscrolldiagleft(unsigned char start, unsigned char stop);
|
||||
extern void stopscroll();
|
||||
extern void setCursor(short x, short y);
|
||||
extern short getCursorX();
|
||||
extern short getCursorY();
|
||||
extern unsigned char getRotation();
|
||||
extern void invertDisplay(unsigned char i);
|
||||
|
||||
/*SSD1306 Graphics Handling API's */
|
||||
extern signed char drawPixel(short x, short y, short color);
|
||||
extern void writeLine(short x0, short y0, short x1, short y1, short color);
|
||||
extern void drawCircleHelper( short x0, short y0, short r, unsigned char cornername, short color);
|
||||
extern void drawLine(short x0, short y0, short x1, short y1, short color);
|
||||
extern void drawRect(short x, short y, short w, short h, short color);
|
||||
extern void fillRect(short x, short y, short w, short h, short color);
|
||||
extern void drawCircle(short x0, short y0, short r, short color);
|
||||
extern void fillCircleHelper(short x0, short y0, short r, unsigned char cornername, short delta, short color);
|
||||
extern void fillCircle(short x0, short y0, short r, short color);
|
||||
extern void drawTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color);
|
||||
extern void fillTriangle(short x0, short y0, short x1, short y1, short x2, short y2, short color);
|
||||
extern void drawRoundRect(short x, short y, short w, short h, short r, short color);
|
||||
extern void fillRoundRect(short x, short y, short w, short h, short r, short color);
|
||||
extern void drawBitmap(short x, short y, const unsigned char bitmap[], short w, short h, short color);
|
||||
extern short oled_write(unsigned char c);
|
||||
|
||||
/*SSD1306 Text and Character Handling API's */
|
||||
extern void setTextSize(unsigned char s);
|
||||
extern void setTextColor(short c);
|
||||
extern void setTextWrap(bool w);
|
||||
extern void drawChar(short x, short y, unsigned char c, short color, short bg, unsigned char size);
|
||||
extern short print_str(const unsigned char *strPtr);
|
||||
extern short println();
|
||||
extern short print_strln(const unsigned char *strPtr);
|
||||
|
||||
/*SSD1306 Number Handling API's */
|
||||
extern short printNumber(unsigned long n, unsigned char base);
|
||||
extern short printNumber_UL(unsigned long n, int base);
|
||||
extern short printNumber_UL_ln(unsigned long num, int base);
|
||||
extern short printNumber_UI(unsigned int n, int base);
|
||||
extern short printNumber_UI_ln(unsigned int n, int base);
|
||||
extern short printNumber_UC(unsigned char b, int base);
|
||||
extern short printNumber_UC_ln(unsigned char b, int base);
|
||||
extern short printNumber_L(long n, int base);
|
||||
extern short printNumber_L_ln(long num, int base);
|
||||
extern short printNumber_I(int n, int base);
|
||||
extern short printNumber_I_ln(int n, int base);
|
||||
extern short printFloat(double number, unsigned char digits);
|
||||
extern short printFloat_ln(double num, int digits);
|
||||
#endif /* SSD1306_OLED_H_ */
|
||||
|
18
luci-app-oled/src/SSD1306_OLED_Library/gfxfont.h
Normal file
@ -0,0 +1,18 @@
|
||||
#ifndef _GFXFONT_H_
|
||||
#define _GFXFONT_H_
|
||||
|
||||
typedef struct { // Data stored PER GLYPH
|
||||
unsigned short bitmapOffset; // Pointer into GFXfont->bitmap
|
||||
unsigned char width, height; // Bitmap dimensions in pixels
|
||||
unsigned char xAdvance; // Distance to advance cursor (x axis)
|
||||
char xOffset, yOffset; // Dist from cursor pos to UL corner
|
||||
} GFXglyphT, *GFXglyphPtr;
|
||||
|
||||
typedef struct { // Data stored for FONT AS A WHOLE:
|
||||
unsigned char *bitmap; // Glyph bitmaps, concatenated
|
||||
GFXglyphPtr glyph; // Glyph array
|
||||
unsigned char first, last; // ASCII extents
|
||||
unsigned char yAdvance; // Newline distance (y axis)
|
||||
} GFXfontT, *GFXfontPtr;
|
||||
|
||||
#endif // _GFXFONT_H_
|
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (C) 2008-2019 kenzok78
|
||||
# Copyright (C) 2008-2019 Jerrykuku
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
@ -7,8 +7,8 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=Argonne kenzo
|
||||
LUCI_DEPENDS:=+curl +jsonfilter
|
||||
PKG_VERSION:=1.7.7
|
||||
LUCI_DEPENDS:=
|
||||
PKG_VERSION:=1.7.3
|
||||
PKG_RELEASE:=2
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
* Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -17,7 +18,7 @@
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* Agron Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
@ -314,7 +315,7 @@ li {
|
||||
position: relative;
|
||||
}
|
||||
.login-page .login-container .login-form .form-login .input-group::before {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -632,7 +633,7 @@ footer a {
|
||||
position: relative;
|
||||
}
|
||||
.main .main-left .nav li.slide .menu::before {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -651,7 +652,7 @@ footer a {
|
||||
position: absolute;
|
||||
right: 0.5rem;
|
||||
top: 0.8rem;
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -888,7 +889,7 @@ footer a {
|
||||
box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
.cbi-button:active {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
|
||||
}
|
||||
.cbi-button:disabled {
|
||||
cursor: not-allowed;
|
||||
@ -946,34 +947,6 @@ form.inline + form.inline,
|
||||
.cbi-value-field .cbi-button-neutral {
|
||||
min-width: 2.5rem !important;
|
||||
}
|
||||
/* Replace LuCI's default file and folder type icons */
|
||||
img[src="/luci-static/resources/cbi/reload.gif"] {
|
||||
content: url("/luci-static/argonne/img/reload.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/file.gif"] {
|
||||
content: url("/luci-static/argonne/img/file.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/add.gif"] {
|
||||
content: url("/luci-static/argonne/img/add.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/remove.gif"] {
|
||||
content: url("/luci-static/argonne/img/remove.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/edit.gif"] {
|
||||
content: url("/luci-static/argonne/img/edit.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/fieldadd.gif"] {
|
||||
content: url("/luci-static/argonne/img/fieldadd.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/link.gif"] {
|
||||
content: url("/luci-static/argonne/img/link.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/find.gif"] {
|
||||
content: url("/luci-static/argonne/img/find.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/folder.gif"] {
|
||||
content: url("/luci-static/argonne/img/folder.webp");
|
||||
}
|
||||
/* input */
|
||||
.cbi-value input[type="password"],
|
||||
.cbi-value input[type="text"] {
|
||||
@ -1082,13 +1055,12 @@ input[type="checkbox"] {
|
||||
appearance: none !important;
|
||||
-webkit-appearance: none !important;
|
||||
border: 1px solid #dee2e6;
|
||||
width: 17px !important;
|
||||
height: 17px !important;
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
}
|
||||
input[type="checkbox"]:checked {
|
||||
border: 1px solid #5e72e4;
|
||||
@ -1101,8 +1073,7 @@ input[type="checkbox"]:checked {
|
||||
background-position: center;
|
||||
}
|
||||
ul li .cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem !important;
|
||||
vertical-align: middle !important;
|
||||
margin: 0.5rem 0.25rem !important;
|
||||
}
|
||||
.cbi-input-radio {
|
||||
appearance: none !important;
|
||||
@ -1215,7 +1186,7 @@ ul li .cbi-input-checkbox {
|
||||
}
|
||||
.cbi-section-create {
|
||||
margin: 0;
|
||||
padding-left: 0.5rem;
|
||||
padding-left: 1rem;
|
||||
align-items: center;
|
||||
}
|
||||
.cbi-section-create > * {
|
||||
@ -1274,41 +1245,10 @@ small {
|
||||
.cbi-section > legend {
|
||||
display: none !important;
|
||||
}
|
||||
/* Define the error text border breathe display animation */
|
||||
@keyframes error-border-breathe {
|
||||
0%{
|
||||
border-color: #fb6340;
|
||||
}
|
||||
50%{
|
||||
border-color: transparent;
|
||||
}
|
||||
100%{
|
||||
border-color: #fb6340;
|
||||
}
|
||||
}
|
||||
/* Center display error text box */
|
||||
.cbi-section-error > ul{
|
||||
text-align: center;
|
||||
}
|
||||
/* Add border for error text box, and border breathe display animation to make it more noticeable */
|
||||
.cbi-section-error > ul > li {
|
||||
.cbi-section-error {
|
||||
padding: 1.5rem;
|
||||
color: #fb6340;
|
||||
font-weight: 600;
|
||||
max-width: 60%;
|
||||
color: #fb6340;
|
||||
line-height: 1rem;
|
||||
display: inline-block;
|
||||
border: 2px solid #fb6340;
|
||||
border-radius: 0.3rem;
|
||||
animation: error-border-breathe 1.5s ease-in-out infinite;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
.cbi-input-invalid,
|
||||
.cbi-value-error input {
|
||||
color: #fb6340;
|
||||
border: 1px dashed #fb6340;
|
||||
}
|
||||
fieldset > fieldset {
|
||||
margin: 0;
|
||||
@ -1369,7 +1309,6 @@ input[name="nslookup"] {
|
||||
height: 1.6rem !important;
|
||||
line-height: 1.6rem;
|
||||
border-radius: 0.25rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
#swaptotal > div > div,
|
||||
#swapfree > div > div,
|
||||
@ -1461,30 +1400,6 @@ td > table > tbody > tr > td,
|
||||
.a-to-btn {
|
||||
text-decoration: none;
|
||||
}
|
||||
/* file selector button */
|
||||
::file-selector-button {
|
||||
color: #fff;
|
||||
border-radius: .25rem;
|
||||
border: 1px solid #2e6da4;
|
||||
padding: .4rem .5rem;
|
||||
background-color: #337ab7;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
::file-selector-button:hover,
|
||||
::file-selector-button:focus,
|
||||
::file-selector-button:active {
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
::file-selector-button:hover,
|
||||
::file-selector-button:focus {
|
||||
box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
::file-selector-button:active {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23);
|
||||
}
|
||||
/* table */
|
||||
.cbi-section-table .cbi-section-table-titles .cbi-section-table-cell {
|
||||
width: auto !important;
|
||||
@ -1599,40 +1514,6 @@ td > table > tbody > tr > td,
|
||||
#cbi-network-switch_vlan .td {
|
||||
flex-basis: 12%;
|
||||
}
|
||||
/* Fix background color of table-titles */
|
||||
.cbi-section-node > .cbi-section-table > tbody > .cbi-section-table-titles th {
|
||||
background-color: var(--lighter);
|
||||
border: none;
|
||||
}
|
||||
/* Fix background color of table-descr */
|
||||
.cbi-section-node > .cbi-section-table > tbody > .cbi-section-table-descr th {
|
||||
border: none;
|
||||
}
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-1 */
|
||||
.cbi-section-node > .cbi-section-table > tbody > .cbi-rowstyle-1 th {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: none;
|
||||
}
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-2 */
|
||||
.cbi-section-node > .cbi-section-table > tbody > .cbi-rowstyle-2 th {
|
||||
background-color: #f9f9f9;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: none;
|
||||
}
|
||||
/* Change the color of the H label in the table to make it more visible */
|
||||
th h1, td h1,
|
||||
th h2, td h2,
|
||||
th h3, td h3,
|
||||
th h4, td h4,
|
||||
th h5, td h5,
|
||||
th h6, td h6 {
|
||||
background: var(--lighter);
|
||||
}
|
||||
/* OCD: Change the background color of the "now in use" node in PassWall */
|
||||
.cbi-section-table > tbody > ._now_use {
|
||||
background: #5e72e473 !important;
|
||||
}
|
||||
/* language fix */
|
||||
body.lang_pl.node-main-login .cbi-value-title {
|
||||
width: 12rem;
|
||||
@ -1753,7 +1634,7 @@ body.lang_pl.node-main-login .cbi-value-title {
|
||||
.cbi-value-helpicon,
|
||||
.showSide,
|
||||
.main > .loading > span {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal !important;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal !important;
|
||||
@ -1896,20 +1777,12 @@ table > thead > tr > th,
|
||||
.cbi-section-table-row:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-dropdown,
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-select,
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-text,
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-password {
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-password,
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-text,
|
||||
.cbi-section-table-row > .cbi-value-field .cbi-input-password {
|
||||
min-width: 100px;
|
||||
}
|
||||
#lease6_status_table > tbody > .cbi-section-table-row.cbi-rowstyle-1 div,
|
||||
#lease6_status_table > tbody > .cbi-section-table-row.cbi-rowstyle-2 div {
|
||||
min-width: 100%;
|
||||
}
|
||||
.cbi-section-table-row > .cbi-value-field [data-dynlist] > input,
|
||||
.cbi-section-table-row > .cbi-value-field input.cbi-input-password {
|
||||
width: calc(100% - 1.5rem);
|
||||
@ -1927,27 +1800,10 @@ div > .table > .tbody > .tr:nth-of-type(2n) {
|
||||
background-color: var(--danger) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
/* Define the warning background-color breathe display animation */
|
||||
@keyframes warning-background-color-breathe {
|
||||
0%{
|
||||
color: #fff;
|
||||
background-color: #fb6340;
|
||||
}
|
||||
50%{
|
||||
color: #32325d;
|
||||
background-color: #fff;
|
||||
}
|
||||
100%{
|
||||
color: #fff;
|
||||
background-color: #fb6340;
|
||||
}
|
||||
}
|
||||
.warning,
|
||||
.warning * {
|
||||
background-color: #fb6340;
|
||||
background-color: var(--warning);
|
||||
color: #fff;
|
||||
animation: warning-background-color-breathe 1.5s ease-in-out infinite !important;
|
||||
.warning {
|
||||
background-color: #fb6340 !important;
|
||||
background-color: var(--warning) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
.notice {
|
||||
background-color: #5e72e4 !important;
|
||||
@ -2092,6 +1948,7 @@ table > thead > tr > th {
|
||||
padding-top: 0.75rem;
|
||||
padding-bottom: 0.75rem;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
table > tbody > tr:first-child > td,
|
||||
@ -2174,7 +2031,7 @@ td > table > tbody > tr > td {
|
||||
}
|
||||
.cbi-tabmenu {
|
||||
color: white;
|
||||
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||
padding: 0.5rem 1rem 0 1rem;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
border-bottom: 1px solid #ddd !important;
|
||||
@ -2440,7 +2297,7 @@ select[multiple="multiple"] {
|
||||
overflow-y: visible;
|
||||
}
|
||||
.cbi-section-node .cbi-value {
|
||||
padding: 0.5rem 1rem 0.5rem 1rem !important;
|
||||
padding: 0.3rem 1rem 0.3rem 1rem;
|
||||
}
|
||||
.cbi-tabcontainer > .cbi-value:nth-of-type(2n) {
|
||||
background-color: #f9f9f9;
|
||||
@ -2451,18 +2308,6 @@ select[multiple="multiple"] {
|
||||
line-height: 1.6;
|
||||
font-size: 0.875rem;
|
||||
}
|
||||
/* Fix text position of the luci-app-filebrowser running state */
|
||||
#cbi-filebrowser > .cbi-section > .cbi-section > .cbi-value > .cbi-value-field,
|
||||
/* Fix text position of the luci-apps running state of the [Control] type */
|
||||
form > .cbi-map > .cbi-section > .cbi-section-node > .cbi-value > .cbi-value-field font {
|
||||
word-wrap: break-word;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
padding: 0.7rem;
|
||||
padding-left: 0;
|
||||
text-align: right;
|
||||
display: table-cell;
|
||||
}
|
||||
.cbi-value-helpicon > img {
|
||||
display: none;
|
||||
}
|
||||
@ -2482,6 +2327,7 @@ form > .cbi-map > .cbi-section > .cbi-section-node > .cbi-value > .cbi-value-fie
|
||||
padding: 0.7rem;
|
||||
padding-left: 0;
|
||||
width: 23rem;
|
||||
float: left;
|
||||
text-align: right;
|
||||
display: table-cell;
|
||||
}
|
||||
@ -2669,22 +2515,18 @@ td > .ifacebadge,
|
||||
min-width: 10rem;
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
.cbi-value-field .cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
.cbi-value-field .cbi-input-checkbox,
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
height: 1rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
}
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0rem 0.25rem;
|
||||
}
|
||||
.cbi-input-radio {
|
||||
margin: 0rem 0.25rem;
|
||||
}
|
||||
.cbi-value-field > input + .cbi-value-description {
|
||||
padding: 0;
|
||||
}
|
||||
@ -2705,7 +2547,7 @@ td > .ifacebadge,
|
||||
min-width: 7rem;
|
||||
}
|
||||
.cbi-section-create > .cbi-button-add {
|
||||
margin: 0.75rem 0.75rem 0.75rem 0.25rem;
|
||||
margin: 0.5rem 0.5rem 0.5rem 0.5rem;
|
||||
}
|
||||
.cbi-section-remove {
|
||||
padding: 0.5rem;
|
||||
@ -2809,10 +2651,6 @@ input[name="nslookup"] {
|
||||
border-right: 0 !important;
|
||||
background-color: #5e72e4 !important;
|
||||
background-color: var(--primary) !important;
|
||||
height: 100% !important;
|
||||
background-image: url(../img/trafficbar.png);
|
||||
background-position: left top;
|
||||
animation: sparkle 1500ms linear infinite;
|
||||
}
|
||||
.node-system-leds .cbi-section em {
|
||||
display: block;
|
||||
@ -3014,6 +2852,10 @@ input[name="nslookup"] {
|
||||
header > .fill > .container > .brand {
|
||||
display: inline-block;
|
||||
}
|
||||
.cbi-value-title {
|
||||
width: 9rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.node-network-diagnostics > .main .cbi-map fieldset > div * {
|
||||
width: 100% !important;
|
||||
}
|
||||
@ -3121,6 +2963,12 @@ input[name="nslookup"] {
|
||||
width: 100%;
|
||||
position: relative;
|
||||
}
|
||||
.cbi-value-field .cbi-input-checkbox,
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0rem 0.25rem 0 0.25rem;
|
||||
height: 1rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
.cbi-page-actions > div > input {
|
||||
display: none;
|
||||
}
|
||||
@ -3218,4 +3066,4 @@ input[name="nslookup"] {
|
||||
width: 2.3rem !important;
|
||||
height: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
* Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -17,7 +18,7 @@
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* Agron Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
@ -46,12 +47,12 @@
|
||||
/* ICON Font */
|
||||
|
||||
@font-face {
|
||||
font-family: 'argonne';
|
||||
src: url('../fonts/argonne.eot?u6kthm');
|
||||
src: url('../fonts/argonne.eot?u6kthm#iefix') format('embedded-opentype'),
|
||||
url('../fonts/argonne.ttf?u6kthm') format('truetype'),
|
||||
url('../fonts/argonne.woff?u6kthm') format('woff'),
|
||||
url('../fonts/argonne.svg?u6kthm#argonne') format('svg');
|
||||
font-family: 'argon';
|
||||
src: url('../fonts/argon.eot?u6kthm');
|
||||
src: url('../fonts/argon.eot?u6kthm#iefix') format('embedded-opentype'),
|
||||
url('../fonts/argon.ttf?u6kthm') format('truetype'),
|
||||
url('../fonts/argon.woff?u6kthm') format('woff'),
|
||||
url('../fonts/argon.svg?u6kthm#argon') format('svg');
|
||||
font-weight: normal;
|
||||
font-style: normal;
|
||||
font-display: block;
|
||||
@ -60,7 +61,7 @@
|
||||
[class^="icon-"],
|
||||
[class*=" icon-"] {
|
||||
/* use !important to prevent issues with browser extensions that change fonts */
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
|
@ -3,7 +3,7 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg">
|
||||
<metadata>Generated by IcoMoon</metadata>
|
||||
<defs>
|
||||
<font id="argonne" horiz-adv-x="1024">
|
||||
<font id="argon" horiz-adv-x="1024">
|
||||
<font-face units-per-em="1024" ascent="960" descent="-64" />
|
||||
<missing-glyph horiz-adv-x="1024" />
|
||||
<glyph unicode=" " horiz-adv-x="512" d="" />
|
||||
|
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 690 B |
Before Width: | Height: | Size: 156 KiB After Width: | Height: | Size: 75 KiB |
Before Width: | Height: | Size: 632 B |
Before Width: | Height: | Size: 664 B |
Before Width: | Height: | Size: 566 B |
Before Width: | Height: | Size: 674 B |
Before Width: | Height: | Size: 252 B |
Before Width: | Height: | Size: 480 B |
Before Width: | Height: | Size: 848 B |
Before Width: | Height: | Size: 682 B |
@ -2,6 +2,7 @@
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
* Copyright 2019 Jerrykuku <jerrykuku@qq.com>
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -17,7 +18,7 @@
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* Agron Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
@ -26,6 +27,22 @@
|
||||
* Licensed to the public under the Apache License 2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Font generate by Icomoon<icomoon.io>
|
||||
*/
|
||||
(function ($) {
|
||||
$(".main > .loading").fadeOut();
|
||||
|
||||
/**
|
||||
* trim text, Remove spaces, wrap
|
||||
* @param text
|
||||
* @returns {string}
|
||||
*/
|
||||
function trimText(text) {
|
||||
return text.replace(/[ \t\n\r]+/g, " ");
|
||||
}
|
||||
|
||||
|
||||
var lastNode = undefined;
|
||||
var mainNodeName = undefined;
|
||||
|
||||
@ -51,7 +68,6 @@
|
||||
*/
|
||||
function getCurrentNodeByUrl() {
|
||||
var ret = false;
|
||||
const urlReg = new RegExp(nodeUrl + "$")
|
||||
if (!$('body').hasClass('logged-in')) {
|
||||
luciLocation = ["Main", "Login"];
|
||||
return true;
|
||||
@ -65,7 +81,7 @@
|
||||
var that = $(this);
|
||||
var href = that.attr("href");
|
||||
|
||||
if (urlReg.test(href)) {
|
||||
if (href.indexOf(nodeUrl) != -1) {
|
||||
ulNode.click();
|
||||
ulNode.next(".slide-menu").stop(true, true);
|
||||
lastNode = that.parent();
|
||||
@ -103,6 +119,18 @@
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
|
||||
// define what element should be observed by the observer
|
||||
// and what types of mutations trigger the callback
|
||||
if ($("#cbi-dhcp-lan-ignore").length > 0) {
|
||||
observer.observe(document.getElementById("cbi-dhcp-lan-ignore"), {
|
||||
subtree: true,
|
||||
attributes: true
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* hook menu click and add the hash
|
||||
*/
|
||||
@ -125,7 +153,7 @@
|
||||
window.location = $($(this).find("a")[0]).attr("href");
|
||||
return false;
|
||||
});
|
||||
|
||||
|
||||
/**
|
||||
* fix submenu click
|
||||
*/
|
||||
@ -138,11 +166,91 @@
|
||||
/**
|
||||
* get current node and open it
|
||||
*/
|
||||
if (getCurrentNodeByUrl()) {
|
||||
mainNodeName = "node-" + luciLocation[0] + "-" + luciLocation[1];
|
||||
mainNodeName = mainNodeName.replace(/[ \t\n\r\/]+/g, "_").toLowerCase();
|
||||
$("body").addClass(mainNodeName);
|
||||
}
|
||||
|
||||
$(".cbi-button-up").val("");
|
||||
$(".cbi-button-down").val("");
|
||||
|
||||
|
||||
/**
|
||||
* hook other "A Label" and add hash to it.
|
||||
*/
|
||||
$("#maincontent > .container").find("a").each(function () {
|
||||
var that = $(this);
|
||||
var onclick = that.attr("onclick");
|
||||
if (onclick == undefined || onclick == "") {
|
||||
that.click(function () {
|
||||
var href = that.attr("href");
|
||||
if (href.indexOf("#") == -1) {
|
||||
$(".main > .loading").fadeIn("fast");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* Sidebar expand
|
||||
*/
|
||||
var showSide = false;
|
||||
$(".showSide").click(function () {
|
||||
if (showSide) {
|
||||
$(".darkMask").stop(true).fadeOut("fast");
|
||||
$(".main-left").width(0);
|
||||
$(".main-right").css("overflow-y", "auto");
|
||||
showSide = false;
|
||||
} else {
|
||||
$(".darkMask").stop(true).fadeIn("fast");
|
||||
$(".main-left").width("15rem");
|
||||
$(".main-right").css("overflow-y", "hidden");
|
||||
showSide = true;
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$(".darkMask").click(function () {
|
||||
if (showSide) {
|
||||
showSide = false;
|
||||
$(".darkMask").stop(true).fadeOut("fast");
|
||||
$(".main-left").width(0);
|
||||
$(".main-right").css("overflow-y", "auto");
|
||||
}
|
||||
});
|
||||
|
||||
$(window).resize(function () {
|
||||
if ($(window).width() > 921) {
|
||||
$(".main-left").css("width", "");
|
||||
$(".darkMask").stop(true);
|
||||
$(".darkMask").css("display", "none");
|
||||
showSide = false;
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* fix legend position
|
||||
*/
|
||||
$("legend").each(function () {
|
||||
var that = $(this);
|
||||
that.after("<span class='panel-title'>" + that.text() + "</span>");
|
||||
});
|
||||
|
||||
$(".cbi-section-table-titles, .cbi-section-table-descr, .cbi-section-descr").each(function () {
|
||||
var that = $(this);
|
||||
if (that.text().trim() == "") {
|
||||
that.css("padding", "0px");
|
||||
}
|
||||
});
|
||||
|
||||
$(".node-main-login > .main .cbi-value.cbi-value-last .cbi-input-text").focus(function () {
|
||||
//$(".node-main-login > .main > .main-right > .login-bg").addClass("blur");
|
||||
});
|
||||
$(".node-main-login > .main .cbi-value.cbi-value-last .cbi-input-text").blur(function () {
|
||||
//$(".node-main-login > .main > .main-right > .login-bg").removeClass("blur");
|
||||
});
|
||||
|
||||
|
||||
$(".main-right").focus();
|
||||
$(".main-right").blur();
|
||||
$("input").attr("size", "0");
|
||||
|
||||
if (mainNodeName != undefined) {
|
||||
console.log(mainNodeName);
|
||||
@ -165,3 +273,5 @@
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
})(jQuery);
|
@ -1,63 +0,0 @@
|
||||
/**
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
*
|
||||
* luci-theme-bootstrap:
|
||||
* Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
* Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
* Copyright 2012 David Menting <david@nut-bolt.nl>
|
||||
*
|
||||
* MUI:
|
||||
* https://github.com/muicss/mui
|
||||
*
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
* https://unsplash.com/
|
||||
*
|
||||
* Licensed to the public under the Apache License 2.0
|
||||
*/
|
||||
|
||||
/**
|
||||
* Sidebar expand
|
||||
*/
|
||||
var showSide = false;
|
||||
$(".showSide").click(function () {
|
||||
if (showSide) {
|
||||
$(".darkMask").stop(true).fadeOut("fast");
|
||||
$(".main-left").width(0);
|
||||
$(".main-right").css("overflow-y", "auto");
|
||||
showSide = false;
|
||||
} else {
|
||||
$(".darkMask").stop(true).fadeIn("fast");
|
||||
$(".main-left").width("15rem");
|
||||
$(".main-right").css("overflow-y", "hidden");
|
||||
showSide = true;
|
||||
}
|
||||
});
|
||||
|
||||
$(".darkMask").click(function () {
|
||||
if (showSide) {
|
||||
showSide = false;
|
||||
$(".darkMask").stop(true).fadeOut("fast");
|
||||
$(".main-left").width(0);
|
||||
$(".main-right").css("overflow-y", "auto");
|
||||
}
|
||||
});
|
||||
|
||||
$(window).resize(function () {
|
||||
if ($(window).width() > 921) {
|
||||
$(".main-left").css("width", "");
|
||||
$(".darkMask").stop(true);
|
||||
$(".darkMask").css("display", "none");
|
||||
showSide = false;
|
||||
}
|
||||
});
|
@ -1,102 +0,0 @@
|
||||
/**
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
*
|
||||
* luci-theme-bootstrap:
|
||||
* Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
* Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
* Copyright 2012 David Menting <david@nut-bolt.nl>
|
||||
*
|
||||
* MUI:
|
||||
* https://github.com/muicss/mui
|
||||
*
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
* https://unsplash.com/
|
||||
*
|
||||
* Licensed to the public under the Apache License 2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
* Font generate by Icomoon<icomoon.io>
|
||||
*/
|
||||
(function ($) {
|
||||
$(".main > .loading").fadeOut();
|
||||
|
||||
/**
|
||||
* trim text, Remove spaces, wrap
|
||||
* @param text
|
||||
* @returns {string}
|
||||
*/
|
||||
function trimText(text) {
|
||||
return text.replace(/[ \t\n\r]+/g, " ");
|
||||
}
|
||||
|
||||
// define what element should be observed by the observer
|
||||
// and what types of mutations trigger the callback
|
||||
const observer = new MutationObserver(() => {
|
||||
console.log("callback that runs when observer is triggered");
|
||||
});
|
||||
if ($("#cbi-dhcp-lan-ignore").length > 0) {
|
||||
observer.observe(document.getElementById("cbi-dhcp-lan-ignore"), {
|
||||
subtree: true,
|
||||
attributes: true
|
||||
});
|
||||
}
|
||||
|
||||
$(".cbi-button-up").val("");
|
||||
$(".cbi-button-down").val("");
|
||||
|
||||
/**
|
||||
* hook other "A Label" and add hash to it.
|
||||
*/
|
||||
$("#maincontent > .container").find("a").each(function () {
|
||||
var that = $(this);
|
||||
var onclick = that.attr("onclick");
|
||||
if (onclick == undefined || onclick == "") {
|
||||
that.click(function () {
|
||||
var href = that.attr("href");
|
||||
if (href.indexOf("#") == -1) {
|
||||
$(".main > .loading").fadeIn("fast");
|
||||
return true;
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* fix legend position
|
||||
*/
|
||||
$("legend").each(function () {
|
||||
var that = $(this);
|
||||
that.after("<span class='panel-title'>" + that.text() + "</span>");
|
||||
});
|
||||
|
||||
$(".cbi-section-table-titles, .cbi-section-table-descr, .cbi-section-descr").each(function () {
|
||||
var that = $(this);
|
||||
if (that.text().trim() == "") {
|
||||
that.css("padding", "0px");
|
||||
}
|
||||
});
|
||||
|
||||
$(".node-main-login > .main .cbi-value.cbi-value-last .cbi-input-text").focus(function () {
|
||||
//$(".node-main-login > .main > .main-right > .login-bg").addClass("blur");
|
||||
});
|
||||
$(".node-main-login > .main .cbi-value.cbi-value-last .cbi-input-text").blur(function () {
|
||||
//$(".node-main-login > .main > .main-right > .login-bg").removeClass("blur");
|
||||
});
|
||||
|
||||
$(".main-right").focus();
|
||||
$(".main-right").blur();
|
||||
$("input").attr("size", "0");
|
||||
|
||||
})(jQuery);
|
@ -3,6 +3,7 @@
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
* Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -18,7 +19,7 @@
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* Agron Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
@ -361,7 +362,7 @@ li {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -744,7 +745,7 @@ footer {
|
||||
position: relative;
|
||||
|
||||
&::before {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -764,7 +765,7 @@ footer {
|
||||
position: absolute;
|
||||
right: 0.5rem;
|
||||
top: 0.8rem;
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
font-variant: normal;
|
||||
@ -1059,7 +1060,7 @@ footer {
|
||||
}
|
||||
|
||||
.cbi-button:active {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23);
|
||||
box-shadow: 0 10px 20px rgba(0, 0, 0, 0.19), 0 6px 6px rgba(0, 0, 0, 0.23);
|
||||
}
|
||||
|
||||
.cbi-button:disabled {
|
||||
@ -1133,34 +1134,6 @@ form.inline+form.inline,
|
||||
min-width: 2.5rem !important;
|
||||
}
|
||||
|
||||
/* Replace LuCI's default file and folder type icons */
|
||||
img[src="/luci-static/resources/cbi/reload.gif"] {
|
||||
content: url("/luci-static/argonne/img/reload.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/file.gif"] {
|
||||
content: url("/luci-static/argonne/img/file.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/add.gif"] {
|
||||
content: url("/luci-static/argonne/img/add.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/remove.gif"] {
|
||||
content: url("/luci-static/argonne/img/remove.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/edit.gif"] {
|
||||
content: url("/luci-static/argonne/img/edit.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/fieldadd.gif"] {
|
||||
content: url("/luci-static/argonne/img/fieldadd.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/link.gif"] {
|
||||
content: url("/luci-static/argonne/img/link.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/find.gif"] {
|
||||
content: url("/luci-static/argonne/img/find.webp");
|
||||
}
|
||||
img[src="/luci-static/resources/cbi/folder.gif"] {
|
||||
content: url("/luci-static/argonne/img/folder.webp");
|
||||
}
|
||||
|
||||
/* input */
|
||||
.cbi-value input[type="password"],
|
||||
@ -1295,14 +1268,13 @@ input[type="checkbox"] {
|
||||
-webkit-appearance: none !important;
|
||||
border: 1px solid #dee2e6;
|
||||
|
||||
width: 17px !important;
|
||||
height: 17px !important;
|
||||
width: 16px !important;
|
||||
height: 16px !important;
|
||||
padding: 0;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s;
|
||||
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
}
|
||||
|
||||
input[type="checkbox"]:checked {
|
||||
@ -1317,8 +1289,7 @@ input[type="checkbox"]:checked {
|
||||
}
|
||||
|
||||
ul li .cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem !important;
|
||||
vertical-align: middle !important;
|
||||
margin: 0.5rem 0.25rem !important;
|
||||
}
|
||||
|
||||
.cbi-input-radio {
|
||||
@ -1451,7 +1422,7 @@ ul li .cbi-input-checkbox {
|
||||
|
||||
.cbi-section-create {
|
||||
margin: 0;
|
||||
padding-left: 0.5rem;
|
||||
padding-left: 1rem;
|
||||
align-items: center;
|
||||
|
||||
}
|
||||
@ -1524,47 +1495,12 @@ small {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
/* Define the error text border breathe display animation */
|
||||
@keyframes error-border-breathe {
|
||||
0%{
|
||||
border-color: #fb6340;
|
||||
}
|
||||
50%{
|
||||
border-color: transparent;
|
||||
}
|
||||
100%{
|
||||
border-color: #fb6340;
|
||||
}
|
||||
}
|
||||
|
||||
/* Center display error text box */
|
||||
.cbi-section-error > ul{
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/* Add border for error text box, and border breathe display animation to make it more noticeable */
|
||||
.cbi-section-error > ul > li {
|
||||
.cbi-section-error {
|
||||
padding: 1.5rem;
|
||||
color: #fb6340;
|
||||
font-weight: 600;
|
||||
max-width: 60%;
|
||||
color: #fb6340;
|
||||
line-height: 1rem;
|
||||
display: inline-block;
|
||||
border: 2px solid #fb6340;
|
||||
border-radius: 0.3rem;
|
||||
animation: error-border-breathe 1.5s ease-in-out infinite;
|
||||
padding-left: 4px;
|
||||
padding-right: 4px;
|
||||
padding-top: 2px;
|
||||
padding-bottom: 2px;
|
||||
}
|
||||
|
||||
.cbi-input-invalid,
|
||||
.cbi-value-error input {
|
||||
color: #fb6340;
|
||||
border: 1px dashed #fb6340;
|
||||
}
|
||||
|
||||
|
||||
fieldset>fieldset {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
@ -1635,7 +1571,6 @@ input[name="nslookup"] {
|
||||
height: 1.6rem !important;
|
||||
line-height: 1.6rem;
|
||||
border-radius: .25rem;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#swaptotal>div>div,
|
||||
@ -1748,31 +1683,6 @@ td>table>tbody>tr>td,
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
/* file selector button */
|
||||
::file-selector-button {
|
||||
color: #fff;
|
||||
border-radius: .25rem;
|
||||
border: 1px solid #2e6da4;
|
||||
padding: .4rem .5rem;
|
||||
background-color: #337ab7;
|
||||
box-sizing: border-box;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease-in-out;
|
||||
}
|
||||
::file-selector-button:hover,
|
||||
::file-selector-button:focus,
|
||||
::file-selector-button:active {
|
||||
outline: 0;
|
||||
text-decoration: none;
|
||||
}
|
||||
::file-selector-button:hover,
|
||||
::file-selector-button:focus {
|
||||
box-shadow: 0 0px 2px rgba(0, 0, 0, 0.12), 0 2px 2px rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
::file-selector-button:active {
|
||||
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.19), 0 5px 5px rgba(0, 0, 0, 0.23);
|
||||
}
|
||||
|
||||
/* table */
|
||||
|
||||
|
||||
@ -1925,46 +1835,6 @@ td>table>tbody>tr>td,
|
||||
flex-basis: 12%;
|
||||
}
|
||||
|
||||
/* Fix background color of table-titles */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-section-table-titles th {
|
||||
background-color: var(--lighter);
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Fix background color of table-descr */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-section-table-descr th {
|
||||
border: none;
|
||||
}
|
||||
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-1 */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-rowstyle-1 th {
|
||||
background-color: #fff;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-2 */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-rowstyle-2 th {
|
||||
background-color: #f9f9f9;
|
||||
border-top: 1px solid #ddd;
|
||||
border-bottom: none;
|
||||
}
|
||||
|
||||
/* Change the color of the H label in the table to make it more visible */
|
||||
th h1, td h1,
|
||||
th h2, td h2,
|
||||
th h3, td h3,
|
||||
th h4, td h4,
|
||||
th h5, td h5,
|
||||
th h6, td h6 {
|
||||
background: var(--lighter);
|
||||
}
|
||||
|
||||
/* OCD: Change the background color of the "now in use" node in PassWall */
|
||||
.cbi-section-table>tbody>._now_use {
|
||||
background: #5e72e473 !important;
|
||||
}
|
||||
|
||||
/* language fix */
|
||||
body.lang_pl.node-main-login .cbi-value-title {
|
||||
width: 12rem;
|
||||
@ -2119,7 +1989,7 @@ body.lang_pl.node-main-login .cbi-value-title {
|
||||
.cbi-value-helpicon,
|
||||
.showSide,
|
||||
.main>.loading>span {
|
||||
font-family: 'argonne' !important;
|
||||
font-family: 'argon' !important;
|
||||
font-style: normal !important;
|
||||
font-weight: normal !important;
|
||||
font-variant: normal !important;
|
||||
@ -2295,21 +2165,11 @@ table>thead>tr>th,
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-dropdown,
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-select,
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-text,
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-password{
|
||||
width:100%
|
||||
}
|
||||
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-text,
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-password{
|
||||
min-width:100px
|
||||
}
|
||||
|
||||
#lease6_status_table > tbody > .cbi-section-table-row.cbi-rowstyle-1 div,
|
||||
#lease6_status_table > tbody > .cbi-section-table-row.cbi-rowstyle-2 div{
|
||||
min-width:100%;
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-input-password,
|
||||
.cbi-section-table-row>.cbi-value-field .cbi-dropdown {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.cbi-section-table-row>.cbi-value-field [data-dynlist]>input,
|
||||
@ -2333,27 +2193,10 @@ div>.table>.tbody>.tr:nth-of-type(2n) {
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
/* Define the warning background-color breathe display animation */
|
||||
@keyframes warning-background-color-breathe {
|
||||
0%{
|
||||
color: #fff;
|
||||
background-color: #fb6340;
|
||||
}
|
||||
50%{
|
||||
color: #32325d;
|
||||
background-color: #fff;
|
||||
}
|
||||
100%{
|
||||
color: #fff;
|
||||
background-color: #fb6340;
|
||||
}
|
||||
}
|
||||
.warning,
|
||||
.warning * {
|
||||
background-color: #fb6340;
|
||||
background-color: var(--warning);
|
||||
color: #fff;
|
||||
animation: warning-background-color-breathe 1.5s ease-in-out infinite !important;
|
||||
.warning {
|
||||
background-color: #fb6340 !important;
|
||||
background-color: var(--warning) !important;
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
.notice {
|
||||
@ -2530,6 +2373,7 @@ table>thead>tr>th {
|
||||
padding-top: .75rem;
|
||||
padding-bottom: .75rem;
|
||||
letter-spacing: 1px;
|
||||
text-transform: uppercase;
|
||||
border-bottom: 1px solid #e9ecef;
|
||||
}
|
||||
|
||||
@ -2640,7 +2484,7 @@ td>table>tbody>tr>td {
|
||||
|
||||
.cbi-tabmenu {
|
||||
color: white;
|
||||
padding: 0.5rem 0.5rem 0 0.5rem;
|
||||
padding: 0.5rem 1rem 0 1rem;
|
||||
white-space: nowrap;
|
||||
overflow-x: auto;
|
||||
border-bottom: 1px solid #ddd !important;
|
||||
@ -2967,7 +2811,7 @@ select[multiple="multiple"] {
|
||||
|
||||
|
||||
.cbi-section-node .cbi-value {
|
||||
padding: 0.5rem 1rem 0.5rem 1rem !important;
|
||||
padding: 0.3rem 1rem 0.3rem 1rem;
|
||||
}
|
||||
|
||||
|
||||
@ -2983,18 +2827,6 @@ select[multiple="multiple"] {
|
||||
|
||||
}
|
||||
|
||||
/* Fix text position of the luci-app-filebrowser running state */
|
||||
#cbi-filebrowser>.cbi-section>.cbi-section>.cbi-value>.cbi-value-field,
|
||||
/* Fix text position of the luci-apps running state of the [Control] type */
|
||||
form>.cbi-map>.cbi-section>.cbi-section-node>.cbi-value>.cbi-value-field font {
|
||||
word-wrap: break-word;
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.6;
|
||||
padding: 0.7rem;
|
||||
padding-left: 0;
|
||||
text-align: right;
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
|
||||
.cbi-value-helpicon>img {
|
||||
@ -3019,6 +2851,7 @@ form>.cbi-map>.cbi-section>.cbi-section-node>.cbi-value>.cbi-value-field font {
|
||||
padding: .7rem;
|
||||
padding-left: 0;
|
||||
width: 23rem;
|
||||
float: left;
|
||||
text-align: right;
|
||||
display: table-cell;
|
||||
}
|
||||
@ -3264,25 +3097,21 @@ td>.ifacebadge,
|
||||
margin-top: 0.3rem;
|
||||
}
|
||||
|
||||
.cbi-value-field .cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
.cbi-value-field .cbi-input-checkbox,
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
height: 1rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.cbi-input-checkbox {
|
||||
margin: 0.5rem 0.25rem 0.7rem 0.25rem;
|
||||
vertical-align: middle;
|
||||
margin: 0.9rem 0.25rem 0 0.25rem;
|
||||
}
|
||||
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0rem 0.25rem;
|
||||
}
|
||||
|
||||
.cbi-input-radio {
|
||||
margin: 0rem 0.25rem;
|
||||
}
|
||||
|
||||
.cbi-value-field>input+.cbi-value-description {
|
||||
padding: 0;
|
||||
@ -3310,7 +3139,7 @@ td>.ifacebadge,
|
||||
}
|
||||
|
||||
.cbi-section-create>.cbi-button-add {
|
||||
margin: 0.75rem 0.75rem 0.75rem 0.25rem;
|
||||
margin: 0.5rem 0.5rem 0.5rem 0.5rem;
|
||||
}
|
||||
|
||||
.cbi-section-remove {
|
||||
@ -3447,10 +3276,6 @@ input[name="nslookup"] {
|
||||
border-right: 0 !important;
|
||||
background-color: #5e72e4 !important;
|
||||
background-color: var(--primary) !important;
|
||||
height: 100% !important;
|
||||
background-image: url(../img/trafficbar.png);
|
||||
background-position: left top;
|
||||
animation: sparkle 1500ms linear infinite;
|
||||
}
|
||||
}
|
||||
|
||||
@ -3730,10 +3555,17 @@ input[name="nslookup"] {
|
||||
font-size: 1.7rem;
|
||||
}
|
||||
|
||||
|
||||
|
||||
header>.fill>.container>.brand {
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.cbi-value-title {
|
||||
width: 9rem;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
|
||||
.node-network-diagnostics>.main .cbi-map fieldset>div * {
|
||||
width: 100% !important;
|
||||
}
|
||||
@ -3884,6 +3716,13 @@ input[name="nslookup"] {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.cbi-value-field .cbi-input-checkbox,
|
||||
.cbi-value-field .cbi-input-radio {
|
||||
margin: 0rem 0.25rem 0 0.25rem;
|
||||
height: 1rem;
|
||||
line-height: 1.6;
|
||||
}
|
||||
|
||||
.cbi-page-actions>div>input {
|
||||
display: none;
|
||||
}
|
||||
|
@ -3,6 +3,7 @@
|
||||
* Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
*
|
||||
* luci-theme-argonne
|
||||
* Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
*
|
||||
* Have a bug? Please create an issue here on GitHub!
|
||||
* https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -18,7 +19,7 @@
|
||||
* luci-theme-material:
|
||||
* https://github.com/LuttyYang/luci-theme-material/
|
||||
*
|
||||
* Argonne Theme
|
||||
* Agron Theme
|
||||
* https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
*
|
||||
* Login background
|
||||
@ -271,7 +272,6 @@ table>thead>tr>td {
|
||||
|
||||
div {
|
||||
background-color: #32325d !important;
|
||||
background-color: var(--dark-primary) !important;
|
||||
}
|
||||
}
|
||||
|
||||
@ -287,7 +287,7 @@ table>thead>tr>th {
|
||||
}
|
||||
|
||||
.cbi-rowstyle-2 {
|
||||
background-color: #2c2c2c !important;
|
||||
background-color: #1e1e1e;
|
||||
}
|
||||
|
||||
.cbi-rowstyle-1 {
|
||||
@ -306,12 +306,7 @@ table>thead>tr>th {
|
||||
|
||||
.cbi-button {
|
||||
color: #ccc;
|
||||
background-color: #2c2c2c;
|
||||
}
|
||||
|
||||
.cbi-rowstyle-2 .cbi-button-up,
|
||||
.cbi-rowstyle-2 .cbi-button-down {
|
||||
background-color: #252526 !important;
|
||||
background-color: #252526;
|
||||
}
|
||||
|
||||
.cbi-section-node {
|
||||
@ -331,72 +326,6 @@ div>.table>.tbody>.tr:nth-of-type(2n) {
|
||||
background-color: #252526;
|
||||
}
|
||||
|
||||
/* file selector button */
|
||||
::file-selector-button {
|
||||
border: 1px solid darkseagreen !important;
|
||||
background-color: darkseagreen !important;
|
||||
}
|
||||
|
||||
/* Fix background color of table-titles */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-section-table-titles th {
|
||||
background-color: #1e1e1e;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Fix background color of table-descr */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-section-table-descr th {
|
||||
background-color: #333333;
|
||||
border: none !important;
|
||||
}
|
||||
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-1 */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-rowstyle-1 th {
|
||||
background-color: #252526;
|
||||
border-top: 1px solid #252526;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* Fix background color not change when the H tag is in the table rowstyle-2 */
|
||||
.cbi-section-node>.cbi-section-table>tbody>.cbi-rowstyle-2 th {
|
||||
background-color: #2c2c2c;
|
||||
border-top: 1px solid #252526;
|
||||
border-bottom: none !important;
|
||||
}
|
||||
|
||||
/* Change the color of the H label in the table to make it more visible */
|
||||
th h1, td h1,
|
||||
th h2, td h2,
|
||||
th h3, td h3,
|
||||
th h4, td h4,
|
||||
th h5, td h5,
|
||||
th h6, td h6 {
|
||||
background: var(--gray-dark);
|
||||
}
|
||||
|
||||
/* Improved the background color of each itemes in "UNSAVED CHANGES" (dark mode only) */
|
||||
.uci-change-list del,
|
||||
.uci-change-legend-label del {
|
||||
background-color: #fb74008c;
|
||||
}
|
||||
.uci-change-list var,
|
||||
.uci-change-legend-label var {
|
||||
background-color: #333333;
|
||||
}
|
||||
.uci-change-list ins,
|
||||
.uci-change-legend-label ins {
|
||||
background-color: #00ff0a45 !important;
|
||||
}
|
||||
|
||||
/* OCD: Compatible the background color of the "Add the node via the link" & "USE(node)" pop-up window in PassWall (dark mode only) */
|
||||
#add_link_div,
|
||||
#set_node_div {
|
||||
background-color: #333333f0 !important;
|
||||
box-shadow: #00000094 10px 10px 30px 5px !important;
|
||||
}
|
||||
#add_link_div>.cbi-value>.cbi-value-field>#nodes_link {
|
||||
background: #ccc;
|
||||
}
|
||||
|
||||
#content_syslog {
|
||||
box-shadow: 0 0 0.5rem 0 rgba(0, 0, 0, .35)
|
||||
}
|
||||
@ -535,7 +464,7 @@ select {
|
||||
}
|
||||
|
||||
.ifacebox {
|
||||
background-color: #1e1e1e;
|
||||
background-color: none;
|
||||
border: 1px solid #1e1e1e;
|
||||
}
|
||||
|
||||
@ -555,30 +484,6 @@ select {
|
||||
background-color: #3c3c3c;
|
||||
}
|
||||
|
||||
/* Fix firewall zone: "unspecified -or- create: " background color (dark mode only) */
|
||||
div[onclick$="._fwzone_new').checked=true"] {
|
||||
border: 1px solid #3c3c3c;
|
||||
background-color: transparent !important;
|
||||
}
|
||||
|
||||
/* Improve the background color of "Any zone" and "Device" when ADD/EDIT Rules in Firewall > Traffic Rules (dark mode only) */
|
||||
label[for$=".src_any"],
|
||||
label[for$=".dest_empty"],
|
||||
label[for$=".dest_any"] {
|
||||
background-color: #2888db !important;
|
||||
}
|
||||
|
||||
/* Fix/add background color of wireless signal strength badge for dark mode */
|
||||
td>.ifacebadge,
|
||||
.td>.ifacebadge {
|
||||
background-color: #3c3c3c;
|
||||
}
|
||||
|
||||
/* Improved loading process gif color (dark mode only) */
|
||||
img[src="/luci-static/resources/icons/loading.gif"] {
|
||||
filter: invert(1);
|
||||
}
|
||||
|
||||
div.cbi-value var,
|
||||
td.cbi-value-field var {
|
||||
color: #483d8b;
|
||||
@ -636,37 +541,11 @@ td.cbi-value-field var {
|
||||
background-color: darkolivegreen !important;
|
||||
}
|
||||
|
||||
/* Define the warning background-color breathe display animation (dark mode) */
|
||||
@keyframes warning-background-color-breathe-dark {
|
||||
0%{
|
||||
color: #fff;
|
||||
background-color: darkorange;
|
||||
}
|
||||
50%{
|
||||
color: #ccc;
|
||||
background-color: #333333;
|
||||
}
|
||||
100%{
|
||||
color: #fff;
|
||||
background-color: darkorange;
|
||||
}
|
||||
}
|
||||
.warning,
|
||||
.warning * {
|
||||
animation: warning-background-color-breathe-dark 1.5s ease-in-out infinite !important;
|
||||
}
|
||||
|
||||
.notice {
|
||||
background-color: #483d8b !important;
|
||||
background-color: var(--dark-primary) !important;
|
||||
}
|
||||
|
||||
/* Improved the aleart-message background color during device restart (dark mode only) */
|
||||
.errorbox,
|
||||
.alert-message {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.cbi-input-find,
|
||||
.cbi-input-save,
|
||||
.cbi-button-add,
|
||||
@ -708,30 +587,8 @@ fieldset[id^="cbi-apply-"] {
|
||||
background: #252525;
|
||||
}
|
||||
|
||||
/* Define the error text border breathe display animation (dark mode) */
|
||||
@keyframes error-border-breathe-dark {
|
||||
0%{
|
||||
border-color: darkorange;
|
||||
}
|
||||
50%{
|
||||
border-color: transparent;
|
||||
}
|
||||
100%{
|
||||
border-color: darkorange;
|
||||
}
|
||||
}
|
||||
|
||||
/* Add border for error text box, and border breathe display animation to make it more noticeable (dark mode) */
|
||||
.cbi-section-error>ul>li {
|
||||
.cbi-section-error {
|
||||
color: darkorange;
|
||||
border: 2px solid darkorange ;
|
||||
animation: error-border-breathe-dark 1.5s ease-in-out infinite;
|
||||
}
|
||||
|
||||
.cbi-input-invalid,
|
||||
.cbi-value-error input {
|
||||
color: darkorange;
|
||||
border: 1px dashed darkorange !important;
|
||||
}
|
||||
|
||||
.node-services-vssr .block h4 span{
|
||||
|
@ -1,7 +1,8 @@
|
||||
<%#
|
||||
Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material Argonne Template
|
||||
Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-material and Argonne Template
|
||||
|
||||
luci-theme-argonne
|
||||
Copyright 2019 Jerrykuku <jerrykuku@qq.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -17,7 +18,7 @@
|
||||
luci-theme-material:
|
||||
https://github.com/LuttyYang/luci-theme-material/
|
||||
|
||||
Argonne Theme
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Login background
|
||||
@ -57,28 +58,31 @@
|
||||
</footer>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
// thanks for Jo-Philipp Wich <jow@openwrt.org>
|
||||
var winHeight = $(window).height();
|
||||
$(window).resize(function () {
|
||||
if($(document.body).height() < 525 ){
|
||||
if($(".ftc").css('display') != 'none'){
|
||||
$(".ftc").hide()
|
||||
}
|
||||
}else{
|
||||
if($(".ftc").css('display') == 'none'){
|
||||
$(".ftc").show()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<script>
|
||||
if (window.orientation == 90 || window.orientation == -90) {
|
||||
$(".ftc").hide()
|
||||
<script>
|
||||
// thanks for Jo-Philipp Wich <jow@openwrt.org>
|
||||
var luciLocation = <%= luci.http.write_json(luci.dispatcher.context.path) %>;
|
||||
var winHeight = $(window).height();
|
||||
$(window).resize(function () {
|
||||
var winWidth = $(window).width()
|
||||
if(winWidth < 600){
|
||||
var newHeight = $(this).height();
|
||||
var keyboradHeight = newHeight - winHeight;
|
||||
$(".ftc").css("bottom", keyboradHeight + 30);
|
||||
}
|
||||
</script>
|
||||
if($(document.body).height() < 525 ){
|
||||
if($(".ftc").css('display') != 'none'){
|
||||
$(".ftc").hide()
|
||||
}
|
||||
}else{
|
||||
if($(".ftc").css('display') == 'none'){
|
||||
$(".ftc").show()
|
||||
}
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<script src="<%=media%>/js/styles-argonne.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=media%>/js/script.js"></script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
@ -2,6 +2,7 @@
|
||||
Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI and Argonne Template
|
||||
|
||||
luci-theme-argonne
|
||||
Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -14,7 +15,7 @@
|
||||
MUI:
|
||||
https://github.com/muicss/mui
|
||||
|
||||
Argonne Theme
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
@ -43,7 +44,7 @@
|
||||
local node = disp.context.dispatched
|
||||
|
||||
local categories = disp.node_childs(tree)
|
||||
|
||||
local currentNode = luci.dispatcher.context.path
|
||||
local c = tree
|
||||
local i, r
|
||||
|
||||
@ -107,16 +108,22 @@
|
||||
end
|
||||
end
|
||||
|
||||
local function render_submenu(prefix, node)
|
||||
local function render_submenu(prefix,parent, node)
|
||||
local childs = disp.node_childs(node)
|
||||
if #childs > 0 then
|
||||
write('<ul class="slide-menu">')
|
||||
|
||||
local active = (currentNode[2] == parent) and "active" or ""
|
||||
local display = (currentNode[2] == parent) and 'style="display: block;"' or ""
|
||||
|
||||
write('<ul class="slide-menu %s" %s>' %{
|
||||
active,
|
||||
display
|
||||
})
|
||||
for i, r in ipairs(childs) do
|
||||
local nnode = node.nodes[r]
|
||||
local title = pcdata(striptags(translate(nnode.title)))
|
||||
|
||||
write('<li><a data-title="%s" href="%s">%s</a></li>' %{
|
||||
local subactive = (currentNode[3] == r) and 'class="active"' or ""
|
||||
write('<li %s><a data-title="%s" href="%s">%s</a></li>' %{
|
||||
subactive,
|
||||
title,
|
||||
nodeurl(prefix, r, nnode.query),
|
||||
title
|
||||
@ -131,20 +138,21 @@
|
||||
local childs = disp.node_childs(cattree)
|
||||
if #childs > 0 then
|
||||
write('<ul class="nav">')
|
||||
|
||||
|
||||
for i, r in ipairs(childs) do
|
||||
local nnode = cattree.nodes[r]
|
||||
local grandchildren = disp.node_childs(nnode)
|
||||
|
||||
if #grandchildren > 0 then
|
||||
local active = (currentNode[2] == r) and "active" or ""
|
||||
local title = pcdata(striptags(translate(nnode.title)))
|
||||
local en_title = pcdata(striptags(string.gsub(nnode.title," ","_")))
|
||||
write('<li class="slide"><a class="menu" data-title="%s" href="#">%s</a>' %{
|
||||
write('<li class="slide"><a class="menu %s" data-title="%s" href="#">%s</a>' %{
|
||||
active,
|
||||
en_title,
|
||||
title
|
||||
})
|
||||
|
||||
render_submenu(category .. "/" .. r, nnode)
|
||||
render_submenu(category .. "/" .. r,r, nnode)
|
||||
write('</li>')
|
||||
else
|
||||
local title = pcdata(striptags(translate(nnode.title)))
|
||||
@ -232,11 +240,11 @@
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%=media%>/icon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%=media%>/icon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%=media%>/icon/favicon-16x16.png">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json" crossorigin="use-credentials">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="msapplication-TileImage" content="<%=media%>/icon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="<%=bar_color%>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css<%# ?v=PKG_VERSION %>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css?v=<%=math.random(1,100000)%>">
|
||||
<style title="text/css">
|
||||
<% if mode == 'normal' then %>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
@ -265,11 +273,11 @@
|
||||
<% end -%>
|
||||
<script src="<%=resource%>/cbi.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=resource%>/xhr.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=media%>/js/jquery.min.js?v=3.5.1"></script>
|
||||
<script src="<%=media%>/js/jquery.min.js<%# ?v=PKG_VERSION %>"></script>
|
||||
</head>
|
||||
|
||||
<body
|
||||
class="<%- if node then %><%= striptags( node.title ) %><%- end %> <% if luci.dispatcher.context.authsession then %>logged-in<% end %> lang_<%=luci.i18n.context.lang%> <%=mode %> ">
|
||||
class="<%- if node then %><%= striptags( node.title ) %><%- end %> <% if luci.dispatcher.context.authsession then %>logged-in<% end %> lang_<%=luci.i18n.context.lang%> ">
|
||||
|
||||
<div class="main">
|
||||
<div class="main-left">
|
||||
@ -318,12 +326,3 @@
|
||||
</noscript>
|
||||
|
||||
<% if category then render_tabmenu(category, cattree) end %>
|
||||
|
||||
<script>
|
||||
// thanks for Jo-Philipp Wich <jow@openwrt.org>
|
||||
var luciLocation = <%= luci.http.write_json(luci.dispatcher.context.path) %>;
|
||||
</script>
|
||||
|
||||
<script src="<%=media%>/js/menu-argonne.js<%# ?v=PKG_VERSION %>"></script>
|
||||
|
||||
<script src="<%=media%>/js/sidebar-argonne.js<%# ?v=PKG_VERSION %>"></script>
|
||||
|
@ -2,6 +2,7 @@
|
||||
Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI and Argonne Template
|
||||
|
||||
luci-theme-argonne
|
||||
Copyright 2020 Jerryk <jerrykuku@gmail.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -14,7 +15,7 @@
|
||||
MUI:
|
||||
https://github.com/muicss/mui
|
||||
|
||||
Argonne Theme
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
@ -65,70 +66,69 @@
|
||||
bar_color = mode == 'dark' and dark_primary or primary
|
||||
end
|
||||
-%>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html lang="<%=luci.i18n.context.lang%>">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI
|
||||
</title>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="format-detection" content="telephone=no, email=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="x5-fullscreen" content="true">
|
||||
<meta name="full-screen" content="yes">
|
||||
<meta name="x5-page-mode" content="app">
|
||||
<meta name="browsermode" content="application">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="application-name" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<meta name="apple-mobile-web-app-title" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<%=media%>/icon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%=media%>/icon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<%=media%>/icon/apple-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="<%=media%>/icon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%=media%>/icon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%=media%>/icon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%=media%>/icon/favicon-16x16.png">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json" crossorigin="use-credentials">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="msapplication-TileImage" content="<%=media%>/icon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="<%=bar_color%>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css<%# ?v=PKG_VERSION %>">
|
||||
<style title="text/css">
|
||||
<% if mode == 'normal' then %>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
<%=dark_css%>
|
||||
}
|
||||
<% elseif mode == 'dark' then %>
|
||||
<%=dark_css%>
|
||||
<% end -%>
|
||||
<% if fs.access('/etc/config/argonne') then %>
|
||||
:root {
|
||||
--primary: <%=primary%>;
|
||||
--dark-primary: <%=dark_primary%>;
|
||||
--blur-radius:<%=blur_radius%>px;
|
||||
--blur-opacity:<%=blur_opacity%>;
|
||||
--blur-radius-dark:<%=blur_radius_dark%>px;
|
||||
--blur-opacity-dark:<%=blur_opacity_dark%>;
|
||||
}
|
||||
<% end -%>
|
||||
</style>
|
||||
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
|
||||
<% if node and node.css then %>
|
||||
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
|
||||
<% end -%>
|
||||
<% if css then %>
|
||||
<style title="text/css">
|
||||
<%=css %>
|
||||
</style>
|
||||
<% end -%>
|
||||
<script src="<%=resource%>/cbi.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=resource%>/xhr.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=media%>/js/jquery.min.js?v=3.5.1"></script>
|
||||
<meta charset="utf-8">
|
||||
<title>
|
||||
<%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %> - LuCI
|
||||
</title>
|
||||
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport" />
|
||||
<meta name="format-detection" content="telephone=no, email=no" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<meta name="mobile-web-app-capable" content="yes">
|
||||
<meta name="x5-fullscreen" content="true">
|
||||
<meta name="full-screen" content="yes">
|
||||
<meta name="x5-page-mode" content="app">
|
||||
<meta name="browsermode" content="application">
|
||||
<meta name="msapplication-tap-highlight" content="no">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
|
||||
<meta name="application-name" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
<meta name="apple-mobile-web-app-title" content="<%=striptags( (boardinfo.hostname or "?") ) %> - LuCI">
|
||||
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="<%=media%>/icon/apple-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="<%=media%>/icon/apple-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="<%=media%>/icon/apple-icon-144x144.png">
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="<%=media%>/icon/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="<%=media%>/icon/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="<%=media%>/icon/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="<%=media%>/icon/favicon-16x16.png">
|
||||
<link rel="manifest" href="<%=media%>/icon/manifest.json">
|
||||
<meta name="msapplication-TileColor" content="<%=bar_color%>">
|
||||
<meta name="msapplication-TileImage" content="<%=media%>/icon/ms-icon-144x144.png">
|
||||
<meta name="theme-color" content="<%=bar_color%>">
|
||||
<link rel="stylesheet" href="<%=media%>/css/cascade.css?v=<%=math.random(1,100000)%>">
|
||||
<style title="text/css">
|
||||
<% if mode == 'normal' then %>
|
||||
@media (prefers-color-scheme: dark) {
|
||||
<%=dark_css%>
|
||||
}
|
||||
<% elseif mode == 'dark' then %>
|
||||
<%=dark_css%>
|
||||
<% end -%>
|
||||
<% if fs.access('/etc/config/argonne') then %>
|
||||
:root {
|
||||
--primary: <%=primary%>;
|
||||
--dark-primary: <%=dark_primary%>;
|
||||
--blur-radius:<%=blur_radius%>px;
|
||||
--blur-opacity:<%=blur_opacity%>;
|
||||
--blur-radius-dark:<%=blur_radius_dark%>px;
|
||||
--blur-opacity-dark:<%=blur_opacity_dark%>;
|
||||
}
|
||||
<% end -%>
|
||||
</style>
|
||||
<link rel="shortcut icon" href="<%=media%>/favicon.ico">
|
||||
<% if node and node.css then %>
|
||||
<link rel="stylesheet" href="<%=resource%>/<%=node.css%>">
|
||||
<% end -%>
|
||||
<% if css then %>
|
||||
<style title="text/css"><%=css %></style>
|
||||
<% end -%>
|
||||
<script src="<%=resource%>/cbi.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=resource%>/xhr.js<%# ?v=PKG_VERSION %>"></script>
|
||||
<script src="<%=media%>/js/jquery.min.js<%# ?v=PKG_VERSION %>"></script>
|
||||
</head>
|
||||
|
||||
<body class="<%- if node then %><%= striptags( node.title ) %><%- end %> <% if luci.dispatcher.context.authsession then %>logged-in<% end %> lang_<%=luci.i18n.context.lang%> ">
|
||||
|
@ -1,6 +1,6 @@
|
||||
<%#
|
||||
Copyright 2008 Steven Barth <steven@midlink.org>
|
||||
Copyright 2008-2019 Jo-Philipp Wich <jo@mein.io>
|
||||
Copyright 2008 Jo-Philipp Wich <jow@openwrt.org>
|
||||
Licensed to the public under the Apache License 2.0.
|
||||
-%>
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
Argonne is a clean HTML5 theme for LuCI. It is based on luci-theme-bootstrap and MUI and Argonne Template
|
||||
|
||||
luci-theme-argonne
|
||||
Copyright 2021 Jerryk <jerrykuku@gmail.com>
|
||||
|
||||
Have a bug? Please create an issue here on GitHub!
|
||||
https://github.com/kenzok78/luci-theme-argonne/issues
|
||||
@ -13,8 +14,8 @@
|
||||
|
||||
MUI:
|
||||
https://github.com/muicss/mui
|
||||
|
||||
Argonne Theme
|
||||
|
||||
Agron Theme
|
||||
https://demos.creative-tim.com/argon-dashboard/index.html
|
||||
|
||||
Licensed to the public under the Apache License 2.0
|
||||
@ -22,16 +23,16 @@
|
||||
|
||||
<%+header_login%>
|
||||
<%
|
||||
local util = require "luci.util"
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local json = require "luci.jsonc"
|
||||
local sys = require "luci.sys"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
local util = require "luci.util"
|
||||
local fs = require "nixio.fs"
|
||||
local nutil = require "nixio.util"
|
||||
local sys = require "luci.sys"
|
||||
local json = require "luci.jsonc"
|
||||
local uci = require 'luci.model.uci'.cursor()
|
||||
|
||||
-- Fetch Local Background Media
|
||||
|
||||
local function glob(...)
|
||||
function glob(...)
|
||||
local iter, code, msg = fs.glob(...)
|
||||
if iter then
|
||||
return nutil.consume(iter)
|
||||
@ -40,84 +41,64 @@
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
local imageTypes = " jpg png gif webp "
|
||||
local videoTypes = " mp4 webm "
|
||||
local allTypes = imageTypes .. videoTypes
|
||||
local function fetchMedia(path, themeDir)
|
||||
local backgroundTable = {}
|
||||
local backgroundCount = 0
|
||||
function fetchMedia(path,themeDir)
|
||||
local backgroundTable = {}
|
||||
local backgroundCount = 0
|
||||
for i, f in ipairs(glob(path)) do
|
||||
attr = fs.stat(f)
|
||||
if attr then
|
||||
local ext = fs.basename(f):match(".+%.(%w+)$")
|
||||
if ext ~= nil then
|
||||
ext = ext:lower()
|
||||
end
|
||||
if ext ~= nil and string.match(allTypes, " "..ext.." ") ~= nil then
|
||||
if ext == "jpg" or ext == "png" or ext == "gif" or ext == "mp4" then
|
||||
local bg = {}
|
||||
bg.type = ext
|
||||
bg.url = themeDir .. fs.basename(f)
|
||||
table.insert(backgroundTable, bg)
|
||||
table.insert(backgroundTable,bg)
|
||||
backgroundCount = backgroundCount + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
return backgroundTable, backgroundCount
|
||||
end
|
||||
local function selectBackground(themeDir)
|
||||
local bgUrl = media .. "/img/bg1.jpg"
|
||||
local backgroundType = "Image"
|
||||
local mimeType = ""
|
||||
|
||||
if fs.access("/etc/config/argonne") then
|
||||
local online_wallpaper = uci:get_first('argonne', 'global', 'online_wallpaper') or (uci:get_first('argonne', 'global', 'bing_background') == '1' and 'bing')
|
||||
if (online_wallpaper and online_wallpaper ~= "none") then
|
||||
local picurl = sys.exec("/usr/libexec/argonne/online_wallpaper")
|
||||
if (picurl and picurl ~= '') then
|
||||
return picurl, "Image", ""
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local backgroundTable, backgroundCount = fetchMedia("/www" .. themeDir .. "*", themeDir)
|
||||
if ( backgroundCount > 0 ) then
|
||||
local currentBg = backgroundTable[math.random(1, backgroundCount)]
|
||||
bgUrl = currentBg.url
|
||||
if (string.match(videoTypes, " "..currentBg.type.." ") ~= nil) then
|
||||
backgroundType = "Video"
|
||||
mimeType = "video/" .. currentBg.type
|
||||
end
|
||||
end
|
||||
|
||||
return bgUrl, backgroundType, mimeType
|
||||
return backgroundTable,backgroundCount
|
||||
end
|
||||
|
||||
local boardinfo = util.ubus("system", "board")
|
||||
local bingUrl = "http://www.bing.com/"
|
||||
local bingApiUrl = bingUrl .. "HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US"
|
||||
local themeDir = media .. "/background/"
|
||||
local bgUrl, backgroundType, mimeType = selectBackground(themeDir)
|
||||
local bgUrl = media .. "/img/bg1.jpg"
|
||||
local useBing = fs.access('/etc/config/argonne') and uci:get_first('argonne', 'global', 'bing_background') or "0"
|
||||
local backgroundTable, backgroundCount = fetchMedia("/www" .. themeDir .. "*",themeDir)
|
||||
local backgroundType = "Image"
|
||||
|
||||
function getBing()
|
||||
local bing = sys.exec("wget --timeout=0.5 -qO- '%s'" %bingApiUrl)
|
||||
if (bing and bing ~= '') then
|
||||
bgUrl = bingUrl .. json.parse(bing).images[1].url
|
||||
end
|
||||
end
|
||||
|
||||
if ( useBing == "0" ) then
|
||||
if ( backgroundCount > 0 ) then
|
||||
local currentBg = backgroundTable[math.random(1,backgroundCount)]
|
||||
bgUrl = currentBg.url
|
||||
if (currentBg.type == "mp4" ) then
|
||||
backgroundType = "Video"
|
||||
end
|
||||
end
|
||||
else
|
||||
pcall(getBing)
|
||||
end
|
||||
%>
|
||||
<!-- Login Page Start -->
|
||||
<div class="login-page">
|
||||
|
||||
<% if ( backgroundType == "Video" ) then %>
|
||||
<!-- Video Player Start -->
|
||||
<div class="video">
|
||||
<div class="video ar-flex ar-justify-content-center ar-align-items-center">
|
||||
<video autoplay loop muted id="video">
|
||||
<source src="<%=bgUrl%>" type="<%=mimeType%>">
|
||||
<source src="<%=bgUrl%>" type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
<div class="volume-control mute"></div>
|
||||
<script>
|
||||
$(".volume-control").click(function(){
|
||||
if($(this).hasClass("mute")){
|
||||
$(this).removeClass("mute")
|
||||
$("#video").prop('muted', false);
|
||||
}else{
|
||||
$(this).addClass("mute")
|
||||
$("#video").prop('muted', true);
|
||||
}
|
||||
})
|
||||
</script>
|
||||
<!-- Video Player End -->
|
||||
<% else %>
|
||||
<!-- Image Background Start -->
|
||||
@ -127,12 +108,8 @@
|
||||
<!-- Login Container Start -->
|
||||
<div class="login-container">
|
||||
<div class="login-form">
|
||||
<!-- Logo Start -->
|
||||
<a class="brand" href="/"><img src="<%=media%>/img/argonne.svg" class="icon">
|
||||
<span class="brand-text"><%=striptags( (boardinfo.hostname or "?") ) %></span>
|
||||
</a>
|
||||
<!-- Logo End -->
|
||||
<!-- Login Form Start -->
|
||||
<a class="brand" href="/"><img src="<%=media%>/img/argonne.svg" class="icon"><span
|
||||
class="brand-text"><%=striptags( (boardinfo.hostname or "?") .. ( (node and node.title) and ' - ' .. translate(node.title) or '')) %></span></a>
|
||||
<form class="form-login" method="post" action="<%=pcdata(luci.http.getenv("REQUEST_URI"))%>">
|
||||
|
||||
<%- if fuser then %>
|
||||
@ -153,7 +130,7 @@
|
||||
<input type="submit" value="<%:Login%>" class="cbi-button cbi-button-apply" />
|
||||
</div>
|
||||
</form>
|
||||
<!-- Login Form End -->
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var input = document.getElementsByName('luci_password')[0];
|
||||
if (input)
|
||||
|
@ -1,70 +0,0 @@
|
||||
#!/bin/sh
|
||||
# author jjm2473
|
||||
|
||||
# the script will be excuted when `argonne.@global[0].bing_background == '1'`
|
||||
# defaults to 'bing' to be compatible with old config
|
||||
WEB_PIC_SRC=$(uci -q get argonne.@global[0].online_wallpaper || echo 'bing')
|
||||
CACHE=/var/run/argonne_${WEB_PIC_SRC}.url
|
||||
WRLOCK=/var/lock/argonne_${WEB_PIC_SRC}.lock
|
||||
|
||||
fetch_pic_url() {
|
||||
case $WEB_PIC_SRC in
|
||||
bing)
|
||||
local picpath=$(curl -fks --max-time 3 \
|
||||
"https://www.bing.com/HPImageArchive.aspx?format=js&n=1" |
|
||||
jsonfilter -q -e '@.images[0].url')
|
||||
[ -n "${picpath}" ] && echo "//www.bing.com${picpath}"
|
||||
;;
|
||||
unsplash)
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/1920x1080/daily?wallpapers" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
;;
|
||||
unsplash_*)
|
||||
local collection_id=${WEB_PIC_SRC#unsplash_}
|
||||
curl -fks --max-time 3 \
|
||||
"https://source.unsplash.com/collection/${collection_id}/1920x1080" |
|
||||
sed -E 's#^.*href="([^?]+)\?.*$#\1?fm=jpg\&fit=crop\&w=1920\&h=1080#'
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
try_update() {
|
||||
local lock="$WRLOCK"
|
||||
exec 200>$lock
|
||||
|
||||
if flock -n 200 >/dev/null 2>&1; then
|
||||
local picurl=$(fetch_pic_url)
|
||||
if [ -n "$picurl" ]; then
|
||||
echo "${picurl}" | tee "$CACHE"
|
||||
else
|
||||
if [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
else
|
||||
touch "$CACHE"
|
||||
fi
|
||||
fi
|
||||
flock -u 200 >/dev/null 2>&1
|
||||
elif [ -s "$CACHE" ]; then
|
||||
cat "$CACHE"
|
||||
fi
|
||||
}
|
||||
|
||||
get_url() {
|
||||
if [ -f "$CACHE" ]; then
|
||||
local idle_t=$(($(date '+%s') - $(date -r "$CACHE" '+%s' 2>/dev/null || echo '0')))
|
||||
if [ -s "$CACHE" ]; then
|
||||
if [ $idle_t -le 43200 ]; then
|
||||
cat "$CACHE"
|
||||
return
|
||||
fi
|
||||
else
|
||||
if [ $idle_t -le 120 ]; then
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
try_update
|
||||
}
|
||||
|
||||
get_url
|