Esempio n. 1
0
"""Description: Used for control shadowsocks, for example: add account, del account, flow usage stats.
The method ``start_shadowsocks`` integrates shadowsocks into sspymgr and it will start a shadowsocks server
in a separate thread. ``ssAddr`` can be used to make sure that shadowsocks server and adapter communicate 
with the same address, either unix socks file, either socket.

Author: BriFuture

Date: 2019/03/19
"""

__version__ = "0.0.6"

from sspymgr import convertFlowToByte, getRandomCode, Manager, createLogger
from sspymgr.core import User, WebguiSetting, UserType
logger = createLogger('sscontroller', stream=False, logger_prefix="[Core SSController]")

from .database import Account, AccountFlow
from .adapter import SSController

import sys
def ssAddr(addr2str = False):
    """Get universal address for communicating with shadowsocks server
    """
    if sys.platform.startswith( 'linux' ):
        mgr_addr = '/var/run/sspymgr.sock'
    else:
        mgr_addr = ('127.0.0.1', 6001)

    # some problem in unix sock file, using tcp mode always currently
    mgr_addr = ('127.0.0.1', 6001)
Esempio n. 2
0
# -*- coding: utf-8 -*-
"""Description: This module is used to provide email feature to all
other sub modules so that they can send email by a simple api.

Author: BriFuture

Modified: 2019/03/17 12:35
"""

__version__ = '0.1.2'

from sspymgr import DB, createLogger
from datetime import datetime

logger = createLogger('email', stream=False)


class Email(DB.Model):
    __tablename__ = 'email'
    id = DB.Column(DB.Integer, primary_key=True, autoincrement=True)
    to = DB.Column(DB.String(255), nullable=False)
    content = DB.Column(DB.Text)
    time = DB.Column(DB.DateTime, default=datetime.now)
    subject = DB.Column(DB.String(255))
    ip = DB.Column(DB.String(255))
    type = DB.Column(DB.String(255))
    remark = DB.Column(DB.String(255))
    session = DB.Column(DB.String(255))

    def to_dict(self):
        di = {
Esempio n. 3
0
# -*- coding: utf-8 -*-

from sspymgr import createLogger
logger = createLogger(
    "plugin_sscontroller", stream=False, logger_prefix="[Plugin sscontroller]")
from sspymgr import getRandomCode
from datetime import datetime, timedelta

app = None

from .flow_stats import AccountsChecker
from .flow_stats import FlowStats

import threading
def run_threaded(job_func):
    job_thread = threading.Thread(target=job_func)
    job_thread.start()

def scheduleTasks(schedule):
    recorder = FlowStats(app.m_db)
    app.m_sscontroller.setStats(recorder.recordFlow)
    # schedule.every(10).seconds.do(run_threaded, recorder.record5minToDb)
    schedule.every().minute.at(":57").do(run_threaded, recorder.record5minToDb)
    schedule.every().day.at("23:59").do(run_threaded,  recorder.record1dayToDb)
    accChecker = AccountsChecker(app)
    schedule.every().minutes.do(accChecker.checkAllAccounts)
    logger.debug("Tasks scheduled done")


from sspymgr.core import WebguiSetting
from sspymgr.sscontroller import availiable_port
Esempio n. 4
0
# -*- coding: utf-8 -*-
"""Description: This module is used for communicate with shadowsocks server, it contains basic protocol 
which defines how to communicate with shadowsocks server. Also contains a controller class to provide 
convenient methods for other modules.

Author: BriFuture

Detail: 2019/03/17 12:31
"""

from sspymgr import createLogger
logger = createLogger('sscontroller')

def _ping():
    """Return a tuple that is made up of a message that need to be sent to shadowsocks server 
    and the expected response from shadowsocks server
    """
    return b'ping', b'pong'

def _add_port(port, password, method):
    """Return a tuple that contains 4 elements
    First:  is the message that should be sent to shadowsocks server;
    Second: is the expected response from shadowsocks server;
    Third:  is a bool type value which indicates whether it is account-add operation.
    Fourth: is the port passed in.
    """
    cmd = 'add: {{ "server_port": {:d}, "password": "******", "method": "{:s}" }}'.format(port, password, method)
    return cmd.encode( 'ascii' ), b'ok', True, port

def _remove_port(port):
    """Return a tuple that contains 4 elements, the same as ``_add_port``
Esempio n. 5
0
# -*- coding: utf-8 -*-

from sspymgr import DB, createLogger
logger = createLogger("plugin_annoucement",
                      stream=False,
                      logger_prefix="[Plugin announcement]")

from datetime import datetime


class Announcement(DB.Model):
    """公告数据模型
    """
    __tablename__ = 'announcement'
    id = DB.Column(DB.Integer, primary_key=True)
    title = DB.Column(DB.String(255), nullable=False)
    variant = DB.Column(DB.String(32))  # primary, success, warn
    content = DB.Column(DB.BLOB)
    createtime = DB.Column(DB.DateTime, default=datetime.now)
    top = DB.Column(DB.Integer, default=0)

    def to_dict(self):
        content = self.content.decode(
            'utf-8') if self.content is not None else ''
        di = {
            'id': self.id,
            'title': self.title,
            'variant': self.variant,
            'content': content,
            'createTime': self.createtime.timestamp(),
            'top': self.top,
Esempio n. 6
0
# -*- coding: utf-8 -*-
from sspymgr import DB, \
    createLogger, getRandomCode, formatTime

logger = createLogger("plugin_order", stream=False, logger_prefix="[Plugin Order]")

from datetime import datetime, timedelta
from sqlalchemy.sql import text


class Product(DB.Model):
    __tablename__ = 'product'
    id = DB.Column(DB.Integer, primary_key=True, autoincrement=True)
    # name = DB.Column( DB.String( 255 ) )
    type = DB.Column(DB.Integer)  # 0 or none stands by enabled
    flow = DB.Column(DB.Integer)  # unit: Mn
    price = DB.Column(DB.Float)  # unit: ¥
    enable = DB.Column(DB.Boolean, default=True)
    duration = DB.Column(DB.Integer)  # unit: seconds
    buffer_period = DB.Column(DB.Integer)  # unit: seconds

    @staticmethod
    def add_type(price: float, flow: int, duration: timedelta,
                 buffer_period: timedelta):
        dseconds = duration.total_seconds()
        bseconds = buffer_period.total_seconds()
        ot = Product(
            price=price, flow=flow, duration=dseconds, buffer_period=bseconds)
        return ot

    def to_dict(self):
Esempio n. 7
0
annotations or text are mixed in many parts, so one of the jobs TODO is to rewrite all of them in English 
and then use ``gettext`` module to translate them into Chinses.

Author: BriFuture

Date: 2019/03/18 21:51
"""

from sspymgr import DB, createLogger
from sspymgr import getRandomCode, convertFlowToByte

from flask import session, request, jsonify
from datetime import datetime, timedelta
import hashlib

logger = createLogger("core_user", stream=False, logger_prefix="[Plugin User]")


class User(DB.Model):
    """The life cycle of an webserver user is not clear now. So the user type may be
    confusing. TODO reconstruct this model
    """
    __tablename__ = 'user'
    id = DB.Column(DB.Integer, primary_key=True, autoincrement=True)
    type = DB.Column(DB.String(255))
    salt = DB.Column(DB.String(8), nullable=False)
    email = DB.Column(DB.String(255), nullable=False)
    group = DB.Column(DB.Integer, default=0)
    level = DB.Column(DB.Integer, default=1)
    comment = DB.Column(DB.String(255), default='')
    password = DB.Column(DB.String(255), nullable=False)
Esempio n. 8
0
# -*- coding: utf-8 -*-
"""Description: This module stores the settings of webserver provided by sspymgr into database.
The original purpose of this module is to store as much information as possible into a single table, 
But it is proved that it's much better to store settings with simple and enumerable types, such as
String and Number (most common). It will take some time to review this module and make some improvements.

Author: BriFuture

Date: 2019/03/18 21:42
"""
from sspymgr import DB, createLogger
from sqlalchemy.sql import text
from base64 import b64decode

logger = createLogger('core_settings',
                      stream=False,
                      logger_prefix="[Plugin Settings]")

db = None


class WebguiSetting(DB.Model):
    """ TODO reconstruct this model
    Type (can be ignored, just used as utility):
        String: Value type by default, should be processed by other logic
        Image: Value are encoded with base64 format
        Number: Treat value as number( use float builtin function), 
        Boolean: are stored in number with only two candicates (0 or 1)
        Json: Value are encoded with json format
        Hidden: Not visible for even manager
    """