text:
<file_sep>import logging

logging.basicConfig(level=logging.INFO,
                    filename='example.log',
                    filemode='a', # default is append
                    format='%(asctime)s %(levelname)s: %(message)s',
                    datefmt='%m/%d/%Y %I:%M:%S %p'
                    ) # default level is WARNING

logging.debug('This message will be ignored') # will not be printed as anything below INFO will be ignored
logging.info('This should be logged')
logging.warning('And, this too')<file_sep>class MyClass(object):
    a = 5 # public
    '''
        self is the object of the class which
        calls this function.

        print(self) and print(myFirstObject) will have
        same hex code if myFirstObject calls this method
    '''
    def sayHello(self):
        print(self)
        print('Hello')

myFirstObject = MyClass()
mySecondObject = MyClass()

'''
     __main__ is namespace
    MyClass is classname
    hexcode is the memory address
'''
print(myFirstObject)
print(mySecondObject)

'''
    Accessing public varible defined inside class
'''
print(myFirstObject.a)

'''
    Accessing methods on class
'''
myFirstObject.sayHello() # passes myFirstObject as the 1st argument

<file_sep>class MyNum():
    def __init__(self,value):
        self.value = value #public variable

    def getValue(self):
        return self.value

myObj = MyNum(5)
print(myObj.getValue())

myObj.value = 6
print(myObj.getValue())<file_sep>'''
    with will automatically run cleanup routine
    like with open() as file will close the file handle
'''

class MyClass:
    def __enter__(self):
        print('Entered')
        print(self)

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("Exited")
        print(self)

    def say_hi(self):
        print('Hi, instance of %s' %(id(self)))

# Without with context
# a = MyClass()
# a.say_hi()

# With with context
with MyClass():
    MyClass().say_hi()

print('After the "with" block')<file_sep>import timeit

print(
    'By Index:',
    timeit.timeit(stmt="mydict['c']",
                  setup="mydict = {'a': 5, 'b': 6, 'c': 7}",
                  number=1000000
                  )
      )
print(
    'By Get:',
    timeit.timeit(stmt="mydict.get('c')",
                  setup="mydict = {'a': 5, 'b': 6, 'c': 7}",
                  number=1000000
                  )
      )

def test(mydict, key):
    return mydict[key]

print(
    'test(mydict, key)',
    timeit.timeit(
                  setup="from __main__ import test;"
                        "mydict={'a': 1, 'b': 2, 'c': 3};"
                        "key='c'",
                  number=1000000
                  )
      )<file_sep>class InstanceCounter(object):
    count = 0

    def __init__(self, value):
        self.val = value
        InstanceCounter.count += 1

    def set_val(self, newVal):
        self.val = newVal

    def get_val(self):
        return self.val

    def get_count(self):
        return InstanceCounter.count

a = InstanceCounter(5)

print(a.get_val())
print(a.get_count())

b = InstanceCounter(6)
print(a.get_count())<file_sep>import json

'''
    loading json from file
'''
with open('test.json') as file:
    json_data = json.load(file)

print(json_data)

'''
    saving json
'''
new_json = '{"title": "Sample Konfabulator Widget","name": "main_window","color": "green"}'

with open('test.json', 'w') as file:
    json.dump(new_json, file)

<file_sep>class MyClass:
    classAttribute = 'Class Attribute'
    def myMethod(self):
        self.instanceAttribute = 'Instance Attribute'

myObject = MyClass()
print(myObject.classAttribute)
myObject.myMethod()
print(myObject.instanceAttribute)

'''
    Python first looks the attribute in instance
    and then searches it on class
'''

class MySecondClass:
    attribute = 'Class Attribute'

    def myMethod(self):
        self.attribute = 'Instance Attritbute'

mySecondObject = MySecondClass()
print('-- Second Class--')
print(mySecondObject.attribute)
mySecondObject.myMethod()
print(mySecondObject.attribute)

del(mySecondObject.attribute)
print(mySecondObject.attribute)<file_sep>import abc

class GetSetParent:
    __metaclass__ = abc.ABCMeta

    def __init__(self, val):
        self.val = val

    def set_val(self, val):
        self.val = val

    def get_val(self):
        return self.val

    @abc.abstractmethod
    def showdoc(self):
        return

class GetSetInt(GetSetParent):
    def set_val(self, val):
        if not isinstance(val, int):
            val = 0

        super().set_val(val)

    def showdoc(self):
        print("GetSetInt objece ({0}), only accepts integer values".format(id(self)) )

a = GetSetInt(3)
a.set_val(5)
print(a.get_val())
a.showdoc()

class GetSetList(GetSetParent):
    def __init__(self, value = 0):
        self.vallist = [value]

    def get_val(self):
        return self.vallist[-1]

    def get_vals(self):
        return self.vallist

    def set_val(self, val):
        self.vallist.append(val)

    def showdoc(self):
        print("GetSetList object, len {0}, stores history of values set".format(len(self.vallist)))

getSetList = GetSetList(5)
getSetList.set_val(10)
getSetList.set_val(20)
print(getSetList.get_val())
print(getSetList.get_vals())
getSetList.showdoc()
<file_sep>'''
    Handling Exceptions
'''
import sys
mydict = {'a': 1, 'b': 2, 'c': 3, 'd': 4}

key = input('please input a key: ')

try:
    print("The value for {0} is {1}".format(key, mydict[key]))

except KeyError as err:
    print('the key ' + key + ' does not exists')
    print(err)
    # print(sys.exc_info()[0])

'''
    Raising Exceptions
'''

def divideByZero(num):
    return num / 0

try:
    divideByZero(5)
except ZeroDivisionError as error:
    raise ZeroDivisionError("ZeroDivisionError: You cannot divide a number by zero")
<file_sep>'''
 Some Commmands :
 next : for next line execution (only sticks to current context; i.e don't enter the function)
 continue : to continue the program
 step : for next step by step line execution including passing to other frames/context i.e enters the functions
 help : list all available commands
'''

import pdb

sum = 0

for i in range(1, 10):
    sum += 1
    pdb.set_trace()
<file_sep>'''
For Cyclic Diamond Inheritance Resolution like
If D inherits B and C and both B and C inherits A
the method resoultion order will be B, C, A
'''

class A:
    pass

class B(A):
    pass

class C(A):
    pass

class D(B, C):
    pass

print(D.mro())<file_sep>'''
Pickle is python-native object storage.
It can store most Python objects on disk but doesn't
store classes, modules or functions but can refer to them
'''

import pickle

mylist = ['a', 'b', 'c', 'd']

# Saving mylist
with open('datafile.txt', 'wb') as file:
    pickle.dump(mylist, file)

# Getting Content
with open('datafile.txt', 'rb') as file:
    unpickled_list = pickle.load(file)

print(unpickled_list)

'''
    pickling in variable
'''

pickled_list = pickle.dumps(mylist)
print(pickle.loads(pickled_list))

'''
    Saving Instance
'''

class MyClass:
    def __init__(self, value):
        self.value = value

    def increment(self):
        self.value += 1

my_object = MyClass(5)
my_object.increment()
my_object.increment()

with open('datafile.txt', 'wb') as file:
    pickle.dump(my_object, file)

with open('datafile.txt', 'rb') as file:
    unpickled_my_object = pickle.load(file)

print(unpickled_my_object)
print(unpickled_my_object.value)<file_sep>class InstanceCounter:
    count = 0

    def __init__(self, value):
        self.val = value
        InstanceCounter.count += 1

    def set_val(self, newVal):
        self.val = newVal

    def get_val(self):
        return self.val
    '''
        Even thought the method is called on
        class instance, the class is passed as
        the first parameter

        cls stores class
    '''
    @classmethod
    def get_count(cls):
        print(cls)
        return cls.count

a = InstanceCounter(5)
print("Value of a: %s" %(a.get_val()))
print("count: %s" %(a.get_count()))
b = InstanceCounter(13)
print("Value of b: %s" %(b.get_val()))
print("count: %s" %(b.get_count()))
<file_sep>class Date(object):
    def get_date(self):
        return '2014-10-23'

class Time(Date):
    def get_time(self):
        return '08:13:07'

date = Date()
print(date.get_date())

time = Time()
print(time.get_time())
print(time.get_date())<file_sep>'''
When multiple class are inherited. Example D inherits B And C, C interherits B
and B inherits A. Python will look in Depth First Search Order

If method is invoked on instance of D. python will look for
method implementation first in C, if it doesn't find it will
look then inorder B, A , C
'''

class A():
    pass

class B(A):
    pass

class C():
    pass

class D(B, C):
    pass

print(D.mro())
<file_sep>class Animal(object):
    def __init__(self, name):
        self.name = name

    def eat(self, thing):
        print("%s is eating %s" %(self.name, thing))

class Dog(Animal):
    def fetch(self, thing):
        print("%s goes after the %s" %(self.name, thing))

class Cat(Animal):
    def swatString(self):
        print("%s shreds the string" %(self.name))

dog = Dog('Rover')
cat = Cat('Fluffy')

dog.fetch('paper')
cat.swatString()
dog.eat('dog food')
cat.eat('cat food')<file_sep>'''
Variable Naming: Public and private
for more info: https://www.python.org/dev/peps/pep-0008/

Public attributes or variable: regular_lower_case
private attributes or variables: _single_leading_underscore
private attributes that shouldnot be subclassed: __double_leading_underscore
Magic attributes: __double_underscores__ (dont create magic attributes)

Although, there are name conventions for encapsulation, python
do not enforce privacy and trust the use to respect it. All private
variables or attributes can be accessed outside class even the one that
is itended not to be subclassed.
'''

class MyClass:
    a = 0 # public attribute
    _b = 1 # private attribute
    __c = 2 # private attribute that shouldn't be subclassed

# python don't enforce privacy. All can be accessed outside of class
my_object = MyClass()
print(my_object.a)
print(my_object._b)
print(my_object._MyClass__c)
<file_sep>import abc
from datetime import datetime

class WriteFile:
    __metaclass__ = abc.ABCMeta

    def __init__(self, filename):
        self.filename = filename

    @abc.abstractmethod
    def write(self):
        return

    def write_line(self, text):
        # with will automatically run cleanup routine i.e close the file
        with open(self.filename, 'a') as file:
            file.write(text + '\n')

class DelimFile(WriteFile):
    def __init__(self, filename, delimiter):
        super().__init__(filename)
        self.delimiter = delimiter

    def write(self, list):
        line = self.delimiter.join(list)
        self.write_line(line)

class LogFile(WriteFile):

    def write(self, line):
        date = datetime.now()
        date_string = date.strftime('%Y-%m0-%d %H:%M')
        self.write_line('{0}   {1}'.format(date_string, line))

logFile = LogFile('log.txt')
delimFile = DelimFile('text.csv', ',')

logFile.write('This is a log message')
logFile.write('This is another log message')

delimFile.write(['a', 'b', 'c', 'd'])
delimFile.write(['1', '2', '3', '4'])<file_sep>import re

def process_date(date):

    # make sure that vdate is YYYY-MM-DD

    if not re.search(r'^\d\d\d\d-\d\d-\d\d$', date):
        raise ValueError('Please submit date in YYYY-MM-DD format')

    print('The submitted date is {0}'.format(date))

process_date('1980-01-03')
process_date('1/3/1980')<file_sep>'''
Every thing in the python is the object. While other languages make use
of primitives but in python everything is object
'''

myNumber = 5

print(type(myNumber))

myString = 'test'

print(type(myNumber))

def myFunction():
    return 'Hello';

print(type(myFunction))

# Even the type() is object
print(type(type))

# Find the methods available to the object
print(dir(myString))

class Hello:
    pass

print(type(Hello)) # Even Class is object
print(dir(Hello)) # finde methods available on class<file_sep>

def doubleit(x):
    if not isinstance(x, (int, float)):
        raise TypeError
    return x * 2

'''
    This if Gate ensures that the statements inside this block
    is executed only if the file is compiled itself. i.e from the
    main namespace and the code inside if block
    wont be executed if it is imported to other file
'''
if __name__ == "__main__":
    input_val = input()
    doubled_val = doubleit(input_val)

    print("The value of {0} is {1}".format(input_val, doubled_val))<file_sep>class InstanceCounter:
    count = 0

    def __init__(self, val):
        self.val = self.filterInt(val)
        InstanceCounter.count += 1

    '''
        Even though it is called on the instance
        the instance will not be passed as first
        argument
    '''
    @staticmethod
    def filterInt(val):
        if not isinstance(val, int):
            return 0
        else:
            return val

a = InstanceCounter(5)
print(a.val)
b = InstanceCounter(13)
print(b.val)
c = InstanceCounter('hello')
print(c.val)<file_sep>import random

class Animal:
    def __init__(self, name):
        self.name = name

class Dog(Animal):
    def __init__(self, name):
        super().__init__(name)
        self.breed = random.choice(['Sh<NAME>', 'Beagle', 'Mutt'])

    def fetch(self, thing):
        print("%s goes after the %s!" %(self.name, thing))

dog = Dog('Rover')

print(dog.name)
print(dog.breed)
<file_sep>'''
 + is operator used to concadinate strings,
 add number, append lists. But + is just syntatic
 sugar. What happens under the hood ?

 lets suppose
 var a = 1
 var b = 2
 when we execute a+b , what python does is calls the
 magic method on a
 a.__add__(b)

 Similary other Core Syntax resolutions:

 'abc' in var => var.__contains__('abc')
 var == 'abc' => var.__eq__('abc')
 var[1]       => var.__getitem__(1, 3)
 var[1:3]     => var.__getslice__(1, 3)
 len(var)     => var.__len__()
 print(var)   => var.__repr__()
'''

class SumList:
    def __init__(self, list):
        self.list = list

    def __add__(self, other):
        newList = [ x + y for x, y in zip(self.list, other.list)]

        return SumList(newList)

    def __repr__(self):
        return str(self.list)

a = SumList([1, 2, 3, 4, 5])
b = SumList([100, 200, 300, 400, 500])

print(a + b)<file_sep>import pytest
import myprogram

'''
 Run from terminal using command py.test
'''

def test_doubleit():
    assert myprogram.doubleit(10) == 20

def test_doubleit_type():
    with pytest.raises(TypeError):
        myprogram.doubleit('String')<file_sep># MyList inherits from "list" object but indexes from 1 instead of 0

class MyList(list):      # inherits from list
    def __getitem__(self, index):
        if index == 0: raise IndexError
        if index > 0: index = index - 1
        return list.__getitem__(self,index)  # this method is called when we access
                                             # a value with subscript x[1] etc

    def __setitem__(self, index, value):
        if index == 0: raise IndexError
        if index > 0: index = index - 1
        list.__setitem__(self, index,value)

x = MyList(['a', 'b', 'c']) # __init__() inherited from builtin list

print(x)         # __repr__() inherited from builtin list

x.append('spam') # append() inherited from builtin list

print(x[1])      # 'a' (MyList.__getitem__ customises list superclass method)
                 # index is 1 but reflects 0

print(x[4])

<file_sep>import yaml

my_dict = {'a': 1, 'b': 2, 'c': 3}
my_list = [1, 2, 3, 4, 5]
my_tuple = ('x', 'y', 'z')

loaded_yaml = yaml.dump(my_dict)

print(loaded_yaml)

print(yaml.dump(my_list))
print(yaml.dump(my_tuple))

my_obj = (
    [1, 2, 3, 4, 5],
    {'a': 1, 'b': 2, 'c': 3},
    [
        {'x': 98, 'y': 99, 'z': 100},
        3,
        4
    ],
    {'a': [1, 2, 3], 'b': [4, 5, 6], 'c': [7, 8, 9]}
)

print(yaml.dump(my_obj))

'''
    yaml.load(file_to_load_from) to load yaml file.
    syntax similar to JSON or Pickle
'''

class MyClass:
    def __init__(self, val):
        self.val = val

    def increment(self):
        self.val += 1

a = MyClass(5)
a.increment()
a.increment()

with open('test.yaml', 'w') as file:
    yaml.dump(a, file)

with open('test.yaml', 'r') as file:
    # yaml.safe_load(file) will limit the loading of objects to plain
    # python structures like dictionaries, list and tuples not instances of class
    my_class_object = yaml.load(file)

print(my_class_object.val)<file_sep>import random

class MyClass(object):
    def generateRandom(self):
        self.randomValue = random.randint(1, 10)

myObject = MyClass()
myObject.generateRandom()
print(myObject.randomValue)
<file_sep>'''
   @property shouldnot encapsulate expensive operations,
    because attribute setting looks cheap
'''

class GetSet:

    @property
    def var(self):
        print('Getting the "var" attribute')
        return self.attrval

    @var.setter
    def var(self, value):
        print('Setting the "var" attribute')
        self.attrval = value

    @var.deleter
    def var(self):
        print('Deleting the "var" attribute')
        self.attrval = None

a = GetSet()

a.var = 100
print(a.var)
del(a.var)
print(a.var)

repo_language: Python


text:
<file_sep>lsof -i:3001
<file_sep>package models

import (
	"fmt"
	"github.com/widuu/gomysql"
)

type MyModel struct {
	connection *gomysql.Model
}

var conn *gomysql.Model

func (m *MyModel) Init(filepath string) {
	conn, err := gomysql.SetConfig(filepath)
	if err != nil {
		fmt.Println(err)
	}
	m.connection = conn // 获取数据库连接
}

func (m *MyModel) InsertUser(userRes map[string]interface{}) (num int, err error) {
	t := m.connection.SetTable("user").SetPk("user_id")
	nint, err := t.Insert(userRes)

	return nint, err
}

func (m *MyModel) GetUserInfo(userId int) map[int]map[string]string {
	t := m.connection.SetTable("user")
	//map[string]string
	where := fmt.Sprintf("user_id=%d", userId)
	data := t.Fileds("user_id", "password", "username", "user_type").Where(where).FindOne()
	//fmt.Println(data)
	//fmt.Println("---------------")
	return data
}

func (m *MyModel) GetUserDetails(userId int) map[string]string {
	t := m.connection.SetTable("user")

	where := fmt.Sprintf("user_id=%d", userId)
	data := t.Fileds("user_id", "password", "username", "user_type").Where(where).Find()

	return data
}

func (m *MyModel) UpdateUser(userId int, username string) (num int, err error) {
	t := m.connection.SetTable("user")
	where := fmt.Sprintf("user_id=%d", userId)
	var value = make(map[string]interface{})
	value["username"] = username
	nint, err := t.Where(where).Update(value)

	return nint, err
}

func (m *MyModel) ModifyUser(userId int, username string) interface{} {
	sqlStr := fmt.Sprintf("update user set username='%s' where user_id =%d", username, userId)
	n := m.connection.Query(sqlStr)

	return n
}

func (m *MyModel) GetUserListByGender(gender int) map[int]map[string]string {
	t := m.connection.SetTable("user")
	where := fmt.Sprintf("gender=%d", gender)
	data := t.Fileds("user_id", "password", "username", "user_type", "gender").Where(where).OrderBy("user_id desc,user_type asc").FindAll()

	return data
}
<file_sep>gofmt -w .
go tool vet .
go build -v .
<file_sep>[database]
username = root
password = <PASSWORD>
hostname = 172.17.0.1
charset = utf8
database = test
port = 33061
<file_sep>package dm01

func Sum(x, y float64) float64 {
  return x + y
}

func Sub(a float64, b float64) float64 {
    return a-b
}

func Sqrt(x float64) float64 {
    n:=0.0
    for i:=0;i<1000;i++ {
        n-= (n*n-x)/(2*x)
    }
    return n
}
<file_sep>package main

import (
    "fmt"
    "dbDmApp/controllers"
)

func main(){
    fmt.Println("show dbDmApp")
    result:=dmgz.Sqrt(8)
    fmt.Println("the result is:",result)

    userRes:=users.getAllUsers()
}
<file_sep>package secure

import (
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"fmt"
)

// Mac 七牛AK/SK的对象，AK/SK可以从 https://portal.qiniu.com/user/key 获取。
type Mac struct {
	AccessKey string
	SecretKey []byte
}

// NewMac 构建一个新的拥有AK/SK的对象
func NewMac(accessKey, secretKey string) (mac *Mac) {
	return &Mac{accessKey, []byte(secretKey)}
}

// Sign 对数据进行签名，一般用于私有空间下载用途
func (mac *Mac) Sign(data []byte) (token string) {
	h := hmac.New(sha1.New, mac.SecretKey)
	h.Write(data)

	sign := base64.URLEncoding.EncodeToString(h.Sum(nil))
	return fmt.Sprintf("%s:%s", mac.AccessKey, sign)
}

// SignWithData 对数据进行签名，一般用于上传凭证的生成用途
func (mac *Mac) SignWithData(b []byte) (token string) {
	encodedData := base64.URLEncoding.EncodeToString(b)
	h := hmac.New(sha1.New, mac.SecretKey)
	h.Write([]byte(encodedData))
	digest := h.Sum(nil)
	sign := base64.URLEncoding.EncodeToString(digest)
	return fmt.Sprintf("%s:%s:%s", mac.AccessKey, sign, encodedData)
}<file_sep>#!/bin/sh

CMD_ROOT="/opt/code"
#PROJECT_ROOT="${CMD_ROOT}/martini-test3"
PROJECT_ROOT="${CMD_ROOT}/diorm-demo"

${CMD_ROOT}/xmage_fsnotify -f ${PROJECT_ROOT}/main.go -o ${PROJECT_ROOT}/main

<file_sep>package utils

type ApiResponse struct {
	Code string      `json:"code"`
	Msg  string      `json:"msg,omitempty"`
	Data interface{} `json:"data,omitempty"`
}
<file_sep>package dmgz

func Sqrt(x float64) float64 {
    n:=0.0
    for i:=0;i<1000;i++ {
        n-= (n*n-x)/(2*x)
    }
    return n
}
<file_sep>package router

import (
	"dmhi/handler/users"
	"dmhi/router/middleware"
	"github.com/gin-gonic/gin"
	"net/http"
)

func Load(g *gin.Engine, mw ...gin.HandlerFunc) *gin.Engine {
	// Middlewares.
	g.Use(gin.Recovery())
	g.Use(middleware.NoCache)
	g.Use(middleware.Options)
	g.Use(middleware.Secure)
	g.Use(mw...)
	// 404 Handler.
	g.NoRoute(func(c *gin.Context) {
		c.String(http.StatusNotFound, "The incorrect API route.")
	})

	aug := g.Group("/users")
	{
		aug.GET("/info", user.GetUserInfo)
		aug.GET("/health", user.HealthCheck)
		aug.GET("/secure",user.DisMac)
		aug.POST("/ak",user.GetAkWithToken)
		aug.GET("/akbucket",user.GetUpHostByAkBucket)
	}

	return g
}
<file_sep>package storage

import (
	//"fmt"
	"encoding/base64"
	"encoding/json"
	"errors"
	"strings"
	"time"

	"dm01/secure"
)

// PutPolicy 表示文件策略
type PutPolicy struct {
	Scope               string `json:"scope"`
	Expires             uint32 `json:"deadline"` // 截止时间（以秒为单位）
	FsizeLimit          int64  `json:"fsizeLimit,omitempty"`
	MimeLimit           string `json:"mimeLimit,omitempty"`
	DeleteAfterDays     int    `json:"deleteAfterDays,omitempty"`
}

// UploadToken 方法用来进行上传凭证的生成
func (p *PutPolicy) UploadToken(mac *secure.Mac) (token string) {
	if p.Expires == 0 {
		p.Expires = 3600 // 1 hour
	}
	p.Expires += uint32(time.Now().Unix())

	putPolicyJSON, _ := json.Marshal(p)

	token = mac.SignWithData(putPolicyJSON)
	return
}

func (p *PutPolicy) DecodeWithToken(token string) (ak, bucket string, err error){
	items := strings.Split(token, ":")
	if len(items) != 3 {
		err = errors.New("invalid upload token, format error")
		return
	}

	ak = items[0]
	policyBytes, dErr := base64.URLEncoding.DecodeString(items[2])
	if dErr != nil {
		err = errors.New("invalid upload token, invalid put policy")
		return
	}

	putPolicy := PutPolicy{}
	uErr := json.Unmarshal(policyBytes, &putPolicy)
	//fmt.Println(uErr)
	if uErr != nil {
		err = errors.New("invalid upload token, invalid put policy")
		return
	}

	bucket = strings.Split(putPolicy.Scope, ":")[0]
	return
}<file_sep>package routers

import (
	"diormDm/services"
	//"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

type MyRouter struct {
	*mux.Router
}

var service = new(services.MyServices)

func (r *MyRouter) ServeHTTP(w http.ResponseWriter, req *http.Request) {
	//defer tools.CatchError(w, req)
	r.Router.ServeHTTP(w, req)
}

func NewAPIMux() http.Handler {
	r := &MyRouter{mux.NewRouter()}
	s := r.PathPrefix("/api").Subrouter()
	service.Init("./conf/conf.ini")

	initUserRouters(s)
	initRechargeRouters(s)

	r.PathPrefix("/").Handler(http.StripPrefix("/", http.FileServer(http.Dir("web/"))))
	return r
}
<file_sep>
##假设:
> GO项目工作空间:/home/xmage/html/golang/goworkspace
> GO安装在/home/xmage/developments/golang

> 在当前使用的SHELL：(~/.bash_profile,~/.bashrc,~/.zshrc)

### set golang env configuration

```
export GOPATH=$HOME/html/golang/goworkspace    #设置为go安装的路径
export GOROOT=/home/xmage/developments/golang         #go工作空间的路径
export PATH=$PATH:$GOPATH
export PATH=$PATH:$GOROOT/bin
```
> source ~/.szhrc使设置立即生效
<file_sep>package main

import (
	"fmt"
	"log"
	"net/http"
	//"time"
	//"github.com/widuu/gomysql"
	"diormDm/routers"
	//"./services"
)

func main() {
	//service := new(services.MyServices)
	//service.Init("./conf/conf.ini")
	/*
		service.GetUserInfo(7)
		service.GetUserDetails(6)
		service.UpdateUser(6,"wendy")
	*/
	/*
		service.GetUserListByGender(1)
		service.GetUserListByGender(2)

		var value = make(map[string]interface{})
		value["username"] = "hady"
		value["password"] = "<PASSWORD>"
		value["user_type"]=2
		value["gender"]=2
		newUserId,_ := service.InsertUser(value)
		fmt.Printf("\nnew user id :%d\n",newUserId)
	*/
	//if newUserId>0 {
	//   service.UpdateUser(newUserId,"Helen")
	//}
	//conf := goini.SetConfig("./conf/conf.ini")
	//charset := conf.GetValue("database", "charset")
	//fmt.Println(charset)

	//n := c.Query("INSERT INTO user (`username`,`password`,`user_type`) VALUES ('HeungLy','136600',1),('Poply','136600',2)")
	//fmt.Println(n)
	//d := c.Query("select * from user")
	//fmt.Println(d)
	//t:=c.SetTable("user")
	//fmt.Println(t.Fileds("user_id,username").FindAll())

	//n := c.Query("update user set username='ceshishenma' where user_id =11 ")
	//fmt.Println(n)
	/*
			ut:=c.SetTable("user as u")
		data := ut.Fileds("u.user_id", "d.keywords", "u.username", "u.password","u.user_type","d.age").Join("user_data as d", "u.user_id = d.user_id").FindAll()
		fmt.Println(data)
	*/

	//map[int]map[string]string
	/*
		   data := t.Fileds("user_id", "password", "username","user_type").Where("user_id=7").FindOne()
		   fmt.Println(data)
		   fmt.Println("---------------")
		   userInfo:=data[1]

		   fmt.Println("---------------")
		   fmt.Printf("userId:%s\n",userInfo["user_id"])
		   fmt.Printf("name:%s\n",userInfo["username"])
		   fmt.Printf("userType:%s\n",userInfo["user_type"])
		   fmt.Println("---------------")
		   for _,item := range data{
			   for key,val:=range item{
				   fmt.Printf("item[%s]=%s\t%s\n",key,val,item[key])
			   }
		   }
		   fmt.Printf("\n")
		   gomysql.Print(data)

		   details := t.Fileds("user_id", "password", "username","user_type").Where("user_id=7").Find()
		   fmt.Printf(details["username"])
	*/

	/*
		n = c.Query("update user set username='ceshishenma' where id =17 ")
		fmt.Println(n)

		n = c.Query("delete from user where id=16 ")
		fmt.Println(n)

		data = c.Query("select username,password from user")
		fmt.Println(data)

		var value = make(map[string]interface{})
		value["username"] = "widuu"
		value["password"] = "<PASSWORD>"
		_, err = t.Insert(value)
		fmt.Println(err)

		n, err = c.SetTable("user").Delete("id = 16")
		fmt.Println(n, err)

		var sss = make(map[string]interface{})
		sss["username"] = "widuuweb"
		r, err := t.Where("username = 'widuu'").Update(sss)
		fmt.Println(r, err)

		data = c.SetTable("user").SetParam([]string{"*"}).Where("id>1").Limit(1, 5).OrderBy("id Desc").FindAll()
		for _, v := range data {
			for k, value := range v {
				fmt.Println(k, value)
			}
		}
	*/
    /*
	srv := &http.Server{
		Addr: "0.0.0.0:3001",
		//Addr: "0.0.0.0:3000",
		WriteTimeout: 15 * time.Second,
		ReadTimeout:  15 * time.Second,
		Handler:      routers.NewAPIMux(),
	}
	*/

	hostPort := fmt.Sprintf(":%s", "3002")
	log.Printf("\nStart to listening the incoming requests on http address: %s\n", hostPort)

	// Run our server in a goroutine so that it doesn't block.
	/*
	go func() {
	    if err := srv.ListenAndServe(); err != nil {
		    log.Fatal("ListenAndServe: ", err)
		    fmt.Printf("\nListenAndServe:%v\n", err)
	    }
	}()
	*/

	if err := http.ListenAndServe(":3002", routers.NewAPIMux()); err != nil {
		log.Fatal("ListenAndServe: ", err)
		fmt.Printf("\nListenAndServe:%v\n",err)
	}
}

/*
func startHttp() {
    if err := http.ListenAndServe(":8080", routers.NewAPIMux()); err != nil {
        log.Fatal("ListenAndServe: ", err)
        fmt.Printf("\nListenAndServe:%v\n",err)
    }
}
*/
<file_sep>#文件(build可以文件与可以目录)
go build hihello.go

#目录
go build dmhi

#install只能是目录
go install dmhi
<file_sep>package services

import (
	"diormDm/models"
	"fmt"
)

type MyServices struct{}

var bingo = new(models.MyModel)

func (s *MyServices) Init(filepath string) {
	bingo.Init(filepath)
}

func (s *MyServices) InsertUser(userParams map[string]interface{}) (num int, err error) {
	res, err := bingo.InsertUser(userParams)
	fmt.Println(res)
	fmt.Println("---------------")
	return res, err
}

func (s *MyServices) GetUserInfo(userId int) {
	data := bingo.GetUserInfo(userId)
	fmt.Println(data)
	fmt.Println("---------------")
}

func (s *MyServices) GetUserDetails(userId int) {
	var data = bingo.GetUserDetails(userId)
	fmt.Println(data)
	fmt.Println("---------------")
}

func (s *MyServices) UpdateUser(userId int, username string) {
	var res, _ = bingo.UpdateUser(userId, username)
	fmt.Println(res)
	fmt.Println("---------------")
}

func (s *MyServices) ModifyUser(userId int, username string) {
	var res = bingo.ModifyUser(userId, username)
	fmt.Println(res)
	fmt.Println("---------------")
}

func (s *MyServices) GetUserListByGender(gender int) {
	var res = bingo.GetUserListByGender(gender)
	fmt.Println(res)
	fmt.Println("---------------")
}
<file_sep>package storage

import (
	//"context"
	"fmt"
	"strings"
	"sync"
)

// Zone 为空间对应的机房属性，主要包括了上传，资源管理等操作的域名
type Zone struct {
	SrcUpHosts []string
	CdnUpHosts []string
	RsHost     string
	RsfHost    string
	ApiHost    string
	IovipHost  string
}

func (z *Zone) String() string {
	str := ""
	str += fmt.Sprintf("SrcUpHosts: %v\n", z.SrcUpHosts)
	str += fmt.Sprintf("CdnUpHosts: %v\n", z.CdnUpHosts)
	str += fmt.Sprintf("IovipHost: %s\n", z.IovipHost)
	str += fmt.Sprintf("RsHost: %s\n", z.RsHost)
	str += fmt.Sprintf("RsfHost: %s\n", z.RsfHost)
	str += fmt.Sprintf("ApiHost: %s\n", z.ApiHost)
	return str
}

func (z *Zone) GetRsfHost(useHttps bool) string {

	scheme := "http://"
	if useHttps {
		scheme = "https://"
	}

	return fmt.Sprintf("%s%s", scheme, z.RsfHost)
}

func (z *Zone) GetIoHost(useHttps bool) string {

	scheme := "http://"
	if useHttps {
		scheme = "https://"
	}

	return fmt.Sprintf("%s%s", scheme, z.IovipHost)
}

func (z *Zone) GetRsHost(useHttps bool) string {

	scheme := "http://"
	if useHttps {
		scheme = "https://"
	}

	return fmt.Sprintf("%s%s", scheme, z.RsHost)
}

func (z *Zone) GetApiHost(useHttps bool) string {

	scheme := "http://"
	if useHttps {
		scheme = "https://"
	}

	return fmt.Sprintf("%s%s", scheme, z.ApiHost)
}

// ZoneHuadong 表示华东机房
var ZoneHuadong = Zone{
	SrcUpHosts: []string{
		"up.qiniup.com",
		"up-nb.qiniup.com",
		"up-xs.qiniup.com",
	},
	CdnUpHosts: []string{
		"upload.qiniup.com",
		"upload-nb.qiniup.com",
		"upload-xs.qiniup.com",
	},
	RsHost:    "rs.qbox.me",
	RsfHost:   "rsf.qbox.me",
	ApiHost:   "api.qiniu.com",
	IovipHost: "iovip.qbox.me",
}

// ZoneHuabei 表示华北机房
var ZoneHuabei = Zone{
	SrcUpHosts: []string{
		"up-z1.qiniup.com",
	},
	CdnUpHosts: []string{
		"upload-z1.qiniup.com",
	},
	RsHost:    "rs-z1.qbox.me",
	RsfHost:   "rsf-z1.qbox.me",
	ApiHost:   "api-z1.qiniu.com",
	IovipHost: "iovip-z1.qbox.me",
}

// ZoneHuanan 表示华南机房
var ZoneHuanan = Zone{
	SrcUpHosts: []string{
		"up-z2.qiniup.com",
		"up-gz.qiniup.com",
		"up-fs.qiniup.com",
	},
	CdnUpHosts: []string{
		"upload-z2.qiniup.com",
		"upload-gz.qiniup.com",
		"upload-fs.qiniup.com",
	},
	RsHost:    "rs-z2.qbox.me",
	RsfHost:   "rsf-z2.qbox.me",
	ApiHost:   "api-z2.qiniu.com",
	IovipHost: "iovip-z2.qbox.me",
}

// ZoneBeimei 表示北美机房
var ZoneBeimei = Zone{
	SrcUpHosts: []string{
		"up-na0.qiniup.com",
	},
	CdnUpHosts: []string{
		"upload-na0.qiniup.com",
	},
	RsHost:    "rs-na0.qbox.me",
	RsfHost:   "rsf-na0.qbox.me",
	ApiHost:   "api-na0.qiniu.com",
	IovipHost: "iovip-na0.qbox.me",
}

// ZoneXinjiapo 表示新加坡机房
var ZoneXinjiapo = Zone{
	SrcUpHosts: []string{
		"up-as0.qiniup.com",
	},
	CdnUpHosts: []string{
		"upload-as0.qiniup.com",
	},
	RsHost:    "rs-as0.qbox.me",
	RsfHost:   "rsf-as0.qbox.me",
	ApiHost:   "api-as0.qiniu.com",
	IovipHost: "iovip-as0.qbox.me",
}

// for programmers
var Zone_z0 = ZoneHuadong
var Zone_z1 = ZoneHuabei
var Zone_z2 = ZoneHuanan
var Zone_na0 = ZoneBeimei
var Zone_as0 = ZoneXinjiapo

// UcQueryUp 为查询请求回复中的上传域名信息
type UcQueryUp struct {
	Main   []string `json:"main,omitempty"`
	Backup []string `json:"backup,omitempty"`
	Info   string   `json:"info,omitempty"`
}
var hurryDefaultUcQUeryUp = UcQueryUp{
	Main: []string{
		"up-us101.qiniup.com",
		"up-us102.qiniup.com",
		"up-us103.qiniup.com",
	},
	Backup: []string{
		"upload-us199.qiniup.com",
	},
	Info:    "hurry default machine",
}
var backupHuananUcQUeryUp = UcQueryUp{
	Main: []string{
		"up-nan05.qiniup.com",
		"up-nan06.qiniup.com",
	},
	Backup: []string{
		"upload-nan07.qiniup.com",
	},
	Info:    "backup machine",
}

var (
	zoneMutext sync.RWMutex
	zoneCache  = make(map[string]*Zone)
)

// GetZone 用来根据ak和bucket来获取空间相关的机房信息
func GetZone(ak, bucket string) (zone *Zone, err error) {
	zoneID := fmt.Sprintf("%s:%s", ak, bucket)
	//check from cache
	zoneMutext.RLock() //sync lock
	if v, ok := zoneCache[zoneID]; ok {
		zone = v
	}
	zoneMutext.RUnlock()
	if zone != nil {
		return
	}

    ioHost:="up-as.qiniup.com"
	srcUpHosts := []string{"up-as1-src.qiniup.com"}
	cdnUpHosts := []string{"up-as1-cdn.qiniup.com"}
	var akBucketStr = fmt.Sprintf("%s-%s",ak,bucket)

	if strings.Contains(akBucketStr, "1001ak-src101zone") {
		if backupHuananUcQUeryUp.Main != nil {
		    srcUpHosts = append(srcUpHosts,backupHuananUcQUeryUp.Main...)
		}
	} else if strings.Contains(akBucketStr, "1000ak-src100zone") {
		if hurryDefaultUcQUeryUp.Main != nil {
		    srcUpHosts = append(srcUpHosts, hurryDefaultUcQUeryUp.Main...)
		}
	} else {
		if hurryDefaultUcQUeryUp.Main != nil {
		    srcUpHosts = append(srcUpHosts, hurryDefaultUcQUeryUp.Main...)
		}
	}

	if strings.Contains(akBucketStr, "cdn201ak-cdn201zone") {
		if backupHuananUcQUeryUp.Backup != nil {
		    cdnUpHosts = append(cdnUpHosts, backupHuananUcQUeryUp.Backup...)
		}
	} else if strings.Contains(akBucketStr, "cdn200ak-cdn200zone") {
		if hurryDefaultUcQUeryUp.Backup != nil {
		    cdnUpHosts = append(cdnUpHosts, hurryDefaultUcQUeryUp.Backup...)
		}
	} else {
		if hurryDefaultUcQUeryUp.Backup != nil {
		    cdnUpHosts = append(cdnUpHosts, hurryDefaultUcQUeryUp.Backup...)
		}
	}

	zone = &Zone{
		SrcUpHosts: srcUpHosts,
		CdnUpHosts: cdnUpHosts,
		IovipHost:  ioHost,
		RsHost:     DefaultRsHost,
		RsfHost:    DefaultRsfHost,
		ApiHost:    DefaultAPIHost,
	}

	//set specific hosts if possible
	setSpecificHosts(ioHost, zone)

	zoneMutext.Lock() //sync lock
	zoneCache[zoneID] = zone
	zoneMutext.Unlock() //sync lock
	return
}

func setSpecificHosts(ioHost string, zone *Zone) {
	if strings.Contains(ioHost, "-z1") {
		zone.RsHost = "rs-z1.qbox.me"
		zone.RsfHost = "rsf-z1.qbox.me"
		zone.ApiHost = "api-z1.qiniu.com"
	} else if strings.Contains(ioHost, "-z2") {
		zone.RsHost = "rs-z2.qbox.me"
		zone.RsfHost = "rsf-z2.qbox.me"
		zone.ApiHost = "api-z2.qiniu.com"
	} else if strings.Contains(ioHost, "-na0") {
		zone.RsHost = "rs-na0.qbox.me"
		zone.RsfHost = "rsf-na0.qbox.me"
		zone.ApiHost = "api-na0.qiniu.com"
	} else if strings.Contains(ioHost, "-as0") {
		zone.RsHost = "rs-as0.qbox.me"
		zone.RsfHost = "rsf-as0.qbox.me"
		zone.ApiHost = "api-as0.qiniu.com"
	}
}<file_sep>package dm01

import (
    "fmt"
)

type FileDmObject struct {
    Name string
    Size float64
}

type FileDmNotFound struct {
	Full string
	Spec string
}

func (e *FileDmNotFound) Error() string {
	return fmt.Sprintf("yaml: %s: %q not found", e.Full, e.Spec)
}

type FileTypeDmMismatch struct {
	Full     string
	Spec     string
	Token    string
    Name     string
    Size     float64
	Expected string
}

func (e *FileTypeDmMismatch) ShowInfo() string {
	return fmt.Sprintf("yaml: %s: type mismatch: %q is %T, want %s (at %q)",
		e.Full, e.Spec, e.Name, e.Expected, e.Token)
}

func (a FileTypeDmMismatch) ShowToken() {
    fmt.Println(a.Token)
}
func (a *FileTypeDmMismatch) FunPtrA1() {
    fmt.Println("FunPtrA1")
}
func (a *FileTypeDmMismatch) FunPtrA2() {
    fmt.Println("FunPtrA2")
    fmt.Println(a.Token)
}

<file_sep>package storage

import (
	"math/rand"
	"fmt"
	"errors"
)

// PutExtra 为表单上传的额外可选项
type PutExtra struct {
	// 可选，用户自定义参数，必须以 "x:" 开头。若不以x:开头，则忽略。
	Params map[string]string
	// 可选，当为 "" 时候，服务端自动判断。
	MimeType string
}

// FormDmeroader 表示一个表单DM的对象
type FormDmer struct {
	FormId  string
	Cfg      *Config
}

//首字母大写对外，参数首字母小写不对外private
type FormValues struct {
	FormId       string
	Token        string
	Key          string
	Size         int64
}

type formData struct {
	name      string
	hash     string
}
func (p *formData) renderForm(name string ) *formData {
	hash:=fmt.Sprintf("f_%s_%d", name,rand.Int())
	return &formData{
		name:name,
		hash:hash,
	}
}

// PutRet 为七牛标准的上传回复内容。
// 如果使用了上传回调或者自定义了returnBody，那么需要根据实际情况，自己自定义一个返回值结构体
type PutRet struct {
	Hash         string `json:"hash"`
	Key          string `json:"key"`
}

// NewFormUploader 用来构建一个表单DM的对象
func NewFormDmer(cfg *Config,form_id string) *FormDmer {
	if cfg == nil {
		cfg = &Config{}
	}

	//fmt.Printf("\n Config数据:")
	//fmt.Println(cfg)

	return &FormDmer{
		FormId : form_id,
		Cfg:     cfg,
	}
}

func fetchFormValues(form_id string,key string,token string,size int64) *FormValues {
	data:=formData{}
	rf:=data.renderForm(form_id)
	//return FormValues{}是不行的，必须前加&取“指针”
	return &FormValues{
		FormId       :rf.hash,
		Token        :token,
		Key          :key,
		Size         :size,
	}
}

func (p *FormDmer) PutFetch(uptoken string,key string, size int64, extra *PutExtra) (fetchRes *FormValues,err error) {
	if extra == nil {
		extra = &PutExtra{}
	}

	fetchRes=fetchFormValues("D1888",key,uptoken,size)
	if fetchRes == nil {
		err = errors.New("invalid fetch value")
		return
	}

	fmt.Printf("\n form value:\n")
	fmt.Println(fetchRes)
	return
}

func (p *FormDmer) UpHost(ak, bucket string) (upHost string, err error) {
	var zone *Zone
	if p.Cfg.Zone != nil {
		zone = p.Cfg.Zone
	} else {
		if v, zoneErr := GetZone(ak, bucket); zoneErr != nil {
			err = zoneErr
			return
		} else {
			zone = v
		}
	}

	scheme := "http://"
	if p.Cfg.UseHTTPS {
		scheme = "https://"
	}

	host := zone.SrcUpHosts[0]
	if p.Cfg.UseCdnDomains {
		host = zone.CdnUpHosts[0]
	}

	upHost = fmt.Sprintf("%s%s", scheme, host)
	return
}<file_sep>#!/bin/sh

PROJECT_ROOT="$(pwd)"

EXEC_FILE="${PROJECT_ROOT}/main"
SRC_FILE="${PROJECT_ROOT}/main.go"

go build -o ${EXEC_FILE} ${SRC_FILE}

<file_sep>package main

import (
	"errors"
	"log"
	"net/http"
	"time"

	"dmhi/router"

	"dm01"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/kylelemons/go-gypsy/yaml"
)

const (
	PORT = "8086"
)

func main() {
	fmt.Println("hi golang")
	sum := dm01.Sum(3, 4.2)
	fmt.Println("the sum is:", sum)

	config, err := yaml.ReadFile("conf.yaml")
	if err != nil {
		fmt.Println(err)
	}
	fmt.Println(config.Get("path"))
	fmt.Println(config.GetBool("enabled"))

	fdName := "badBoy"
	//fdSize:=256.32
	spec := "special clothes"
	token := "<KEY>"
	fileType := dm01.FileTypeDmMismatch{
		Full:     spec,
		Spec:     spec,
		Token:    token,
		Expected: "yaml.Scalar",
		Name:     fdName,
		//Size:     fdSize
	}

	log.Print(fileType.ShowInfo())
	log.Print("\n******\n")
	fileType.ShowToken()
	log.Print("\n******\n")
	fileType.FunPtrA1()
	log.Print("\n******\n")
	fileType.FunPtrA2()
	log.Print("\n******\n")

	// Create the Gin engine.
	g := gin.New()

	middlewares := []gin.HandlerFunc{}

	// Routes.
	router.Load(
		// Cores.
		g,
		// Middlwares.
		middlewares...,
	)

	// Ping the server to make sure the router is working.
	go func() {
		if err := pingServer(); err != nil {
			log.Fatal("The router has no response, or it might took too long to start up.", err)
		}
		log.Print("The router has been deployed successfully.")
	}()

	hostPort := fmt.Sprintf(":%s", PORT)
	log.Printf("Start to listening the incoming requests on http address: %s", hostPort)
	log.Printf(http.ListenAndServe(hostPort, g).Error())
}

// pingServer pings the http server to make sure the router is working.
func pingServer() error {
	baseHost := fmt.Sprintf("http://127.0.0.1:%s", PORT)
	for i := 0; i < 3; i++ {
		// Ping the server by sending a GET request to `/health`.
		resp, err := http.Get(baseHost + "/users/health")
		if err == nil && resp.StatusCode == 200 {
			return nil
		}
		log.Print(resp)
		// Sleep for a second to continue the next ping.
		log.Print("Waiting for the router, retry in 1 second.")
		time.Sleep(time.Second)
	}
	return errors.New("Cannot connect to the router.")
}
<file_sep>package user

import (
	"math/rand"
	"fmt"
	"dm01/storage"
	"dm01/secure"
	"github.com/gin-gonic/gin"
	"net/http"
)

var (
	accessKey = "QDM_ACCESS_KEY"
	secretKey = "QDM_SECRET_KEY"
	bucket    = "QDM_TEST_BUCKET"
	testBucket = "TEST_BUCKET_1001"
)

// HealthCheck shows `OK` as the ping-pong result.
func HealthCheck(c *gin.Context) {
	message := "OK"
	c.String(http.StatusOK, "\n"+message)
}

// get user detail info
func GetUserInfo(c *gin.Context) {
	//message := "User Info"
	//c.String(http.StatusOK, "\n"+message)
	c.JSON(http.StatusOK, gin.H{"user_id": 10821038, "nickname": "leely"})
}

func DisMac(c *gin.Context) {
	// 简单上传凭证
	putPolicy := storage.PutPolicy{
		Scope: bucket,
		FsizeLimit:1024,//int64
		MimeLimit:"PNG",
		DeleteAfterDays:7,
	}

	macObj := secure.NewMac(accessKey, secretKey)
	upToken := putPolicy.UploadToken(macObj)
	fmt.Println(putPolicy)
	c.JSON(http.StatusOK, gin.H{"user_id": 10821038, "token": upToken})
}

func GetAkWithToken(c *gin.Context) {
	putPolicy := storage.PutPolicy{}
	upToken :="QDM_ACCESS_KEY:<KEY>"
	//upToken := c.Param("token")
	//upToken :=c.PostForm("token")
	ak, _, gErr := putPolicy.DecodeWithToken(upToken)
	if gErr != nil {
		fmt.Println(gErr)
		//return
	}
	fmt.Println(putPolicy)
	c.JSON(http.StatusOK, gin.H{"ak": ak, "token": upToken})
}

func GetUpHostByAkBucket(c *gin.Context) {
	//var putRet storage.PutRet

	putPolicy := storage.PutPolicy{
		Scope:           testBucket,
		DeleteAfterDays: 7,
	}
	macInstance := secure.NewMac(accessKey, secretKey)
	upToken := putPolicy.UploadToken(macInstance)
	testKey := fmt.Sprintf("testPutFileKey_%d", rand.Int())

    ak:=fmt.Sprintf("testAk_%d", rand.Int())
	bucket:=fmt.Sprintf("testCDN_%d", rand.Int())
	akcfg:=storage.Config{
		Zone:&storage.ZoneHuadong,
		UseHTTPS:true,
		UseCdnDomains:true,
		CentralRsHost:"",
	}

	/**/
	formDmer:=storage.FormDmer{
		FormId:"D10888",
		Cfg:&akcfg,
	}
	//formDmer:=storage.NewFormDmer(&akcfg,"D10888")

	// 可选配置
	/*
	putExtra:=storage.PutExtra{}
	putExtra.MimeType="png";
	putExtra.Params=map[string]string{
		"user_type":"2",
		"sign_flag":"extra_auth",
	}
	*/
	putExtra := &storage.PutExtra{
		MimeType:"png",
		Params: map[string]string{
			"user_type":"2",
		    "sign_flag":"extra_auth",
		},
	}

	putRes,putErr:=formDmer.PutFetch(upToken,testKey,188,putExtra)
	if putErr != nil {
		fmt.Println(putErr)
		return
	}

	upHost,err := formDmer.UpHost(ak,bucket)
	if err != nil {
		fmt.Println(err)
		return
	}

	c.JSON(http.StatusOK, gin.H{"ak": ak, "bucket": bucket,"host":upHost})
}
<file_sep>package routers

import (
	//"diormDm/services"
	//"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

//var service = new(services.MyServices)

func initRechargeRouters(r *mux.Router) {

	//@api/user/login
	s := r.PathPrefix("/recharge").Subrouter()
	s.HandleFunc("/sign", Signhandler)
}

func Signhandler(w http.ResponseWriter, r *http.Request) {
	w.Write([]byte("recharge sign handler"))
}<file_sep>gofmt -w ./main.go
go tool vet ./main.go
go build -v ./main.go
<file_sep>package routers

import (
	//"diormDm/services"
	"fmt"
	"github.com/gorilla/mux"
	"net/http"
)

func initUserRouters(r *mux.Router) {
	//service.Init("./conf/conf.ini")
	/*
		if this.service == nil {
		   this.service = new(services.MyServices)
		}
		this.service.Init("./conf/conf.ini")
	*/
	//@api/user/login
	s := r.PathPrefix("/user").Subrouter()
	s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/add", UserAddHandler)
	s.HandleFunc("/login", UserLoginhandler)
}

func UserLoginhandler(w http.ResponseWriter, r *http.Request) {
	/*
		user := &model.User{}
		tools.UnMarshalJson(r, user)
		resp := &model.Resp{Code: "1001", Msg: "账号或者密码错误"}
		if user.Username == "sweetop" && user.Password == "<PASSWORD>" {
			resp = &model.Resp{Code: "0", Msg: "success"}
		}
		tools.MarshalJson(w, resp)
	*/
	w.Write([]byte("user login handler"))
}

func UserListHandler(w http.ResponseWriter, r *http.Request) {
	/*
		resp := &model.Resp{Code: "0", Msg: "success"}
		users := make([]model.User, 0)
		resp.Data = append(users, model.User{Username: "sweetop"})
		tools.MarshalJson(w, resp)
	*/
	service.GetUserListByGender(1)
}

func UserListAction() {
	/*
		resp := &model.Resp{Code: "0", Msg: "success"}
		users := make([]model.User, 0)
		resp.Data = append(users, model.User{Username: "sweetop"})
		tools.MarshalJson(w, resp)
	*/
	service.GetUserListByGender(1)
}

func UserAddHandler(w http.ResponseWriter, r *http.Request) {
	//w.Write([]byte("user add"))
	var value = make(map[string]interface{})
	value["username"] = "hady"
	value["password"] = "<PASSWORD>"
	value["user_type"] = 2
	value["gender"] = 2
	newUserId, _ := service.InsertUser(value)
	fmt.Printf("\nnew user id :%d\n", newUserId)
}
<file_sep>package users

import (
	"fmt"
	"github.com/widuu/gomysql"
)

func getAllUsers() {
	c, err := gomysql.SetConfig("../conf/conf.ini")
	if err != nil {
		fmt.Println(err)
	}

	data := c.Query("select * from user")

        //data := c.Query("select username,password from user")
	fmt.Println(data)
}
<file_sep>lsof -i:8086

branch_name: refs/heads/master

languages: Markdown Shell INI Go

repo_language: Markdown

repo_name: ahmachan/goworkspace


text:
<repo_name>Kflash/boily<file_sep>/config/setup/setup.js
module.exports = function(runner) {
	runner = runner ? runner : global;
	runner.expect = runner.chai.expect;

	beforeEach(function() {
		runner.sandbox = runner.sinon.sandbox.create();
		runner.stub = runner.sandbox.stub.bind(runner.sandbox);
		runner.spy = runner.sandbox.spy.bind(runner.sandbox);
		runner.mock = runner.sandbox.mock.bind(runner.sandbox);
		runner.useFakeTimers = runner.sandbox.useFakeTimers.bind(runner.sandbox);
		runner.useFakeXMLHttpRequest = runner.sandbox.useFakeXMLHttpRequest.bind(runner.sandbox);
		runner.useFakeServer = runner.sandbox.useFakeServer.bind(runner.sandbox);
	});

	afterEach(function() {
		delete runner.stub;
		delete runner.spy;
		runner.sandbox.restore();
	});
};
<file_sep>/config/gulp/tasks/browser.js
import gulp from 'gulp';
import loadPlugins from 'gulp-load-plugins';
import del from 'del';
import glob from 'glob';
import path from 'path';
import webpack from 'webpack';
import plumber from 'gulp-plumber';
import livereload from 'gulp-livereload';
import webpackStream from 'webpack-stream';
import karma from 'karma';

// Remove our temporary files
gulp.task('clean:tmp', (done) => {
	del(['tmp']).then(() => done());
});

// Set up a livereload environment for our spec runner `test/runner.html`
gulp.task('browser', ['clean:tmp'], () => {
	// Our testing bundle is made up of our unit tests, which
	// should individually load up pieces of our application.
	// We also include the browser setup file.
	const testFiles = glob.sync('./specs/**/*spec.browser.js')
		.concat(glob.sync('./specs/**/*spec.server.js'));
	const allFiles = ['./config/setup/browser.js'].concat(testFiles);

	// Lets us differentiate between the first build and subsequent builds
	let firstBuild = true;

	// This empty stream might seem like a hack, but we need to specify all of our files through
	// the `entry` option of webpack. Otherwise, it ignores whatever file(s) are placed in here.
	return gulp.src('')
		.pipe(plumber())
		.pipe(webpackStream({
			watch: true,
			entry: allFiles,
			output: {
				filename: '__spec-build.js'
			},
			module: {
				loaders: [
					// Use imports loader to hack webpacking sinon.
					// https://github.com/webpack/webpack/issues/177
					{
						test: /sinon\.js/,
						loader: 'imports?define=>false,require=>false'
					},

					// Perform babel transpiling on all non-source, test files.
					{
						test: /\.js$/,
						exclude: /node_modules/,
						loader: 'babel-loader'
					},
					// This allows the test setup scripts to load `package.json`
					{
						test: /\.json$/,
						exclude: /node_modules/,
						loader: 'json-loader'
					}
				]
			},
			plugins: [
				// By default, webpack does `n=>n` compilation with entry files. This concatenates
				// them into a single chunk.
				new webpack.optimize.LimitChunkCountPlugin({
					maxChunks: 1
				})
			],
			devtool: 'inline-source-map'
		}, null, function() {
			if (firstBuild) {
				livereload.listen({
					port: 35729,
					host: 'localhost',
					start: true
				});
			} else {
				livereload.reload('./tmp/__spec-build.js');
			}
			firstBuild = false;
		}))
		.pipe(gulp.dest('./tmp'));
});<file_sep>/config/setup/node.js
global.chai = require('chai');
global.sinon = require('sinon');
global.chai.use(require('sinon-chai'));
global.chai.use(require('chai-as-promised'));

if (!global.document || !global.window) {
	// Setup the jsdom environment
	// @see https://github.com/facebook/react/issues/5046
	const jsdom = require('jsdom').jsdom;

	var doc = jsdom('<!doctype html>');

	// get the window object out of the document
	var win = doc.defaultView;

	// set globals for mocha that make access to document and window feel
	// natural in the test environment
	global.document = doc;
	global.window = win;

	//JSDOM doesn't support localStrage by default, so lets just fake it..
	if (!global.window.localStorage) {
		global.window.localStorage = {
			getItem() { return '{}'; },
			setItem() {}
		};
	}

	// take all properties of the window object and also attach it to the
	// mocha global object
	propagateToGlobal(win);

// from mocha-jsdom https://github.com/rstacruz/mocha-jsdom/blob/master/index.js#L80
	function propagateToGlobal (window) {
		for (var key in window) {
			if (!window.hasOwnProperty(key)) continue;
			if (key in global) continue;

			global[key] = window[key];
		}
	}
}

require('./setup')();
<file_sep>/CHANGELOG.md
# v.4.2.6

- Added rollup-plugin-commonjs support in order to support statements such as:
  `import { render } from 'react-dom'` - Credit: [eliagrady](https://github.com/eliagrady)
- updated dependencies

# v.4.2.1

- add back "normal" Babel 2015 preset, and fixed issue with nodeJS 6

# v.4.1.6

- added support for nodeJS 6
- fixed issues with Travis.yml
- updated dependencies

# v.4.1.0

- refactored Karma
- fixed a few issues with Travis.yml
- updated dependencies

# v.4.0.7

- Travis.yml changed to use the newest Chrome browser by default due to issues ES2015 support in PhantomJS
- Travis now tests on Multiple Operating Systems
- Karma changed to use Chrome browser by default due to issues ES2015 support in PhantomJS
- Made boily NodeJS 6.0 ready

# v.4.0.2

- fixed issue where JSDOM didn't work for server tests
- server tests now runs from package.json. No gulp
- `coverage` changed to `server:cov`
- made babel support nodeJS 5.x 100%
- added new babel 2015 preset
- minor tweaks

# v.3.2.7

- simplified Travis

# v.3.2.4
- refactored jsdom configuration
- updated dependencies

# v.3.2.0

- Fixed a issue where jsDOM failed for React
- updated readme

# v.3.1.9

- Removed fixture support. Kept only jsDom

# v.3.1.8

- Fixed fixture issues

# v.3.1.7

- Fixed an issue where coverage wouldn't work on client side
- added jsdom support
- added fixtures. The fixtures can be used like this `this.setFixtures('<div></div>');` inside `beforeEach()`. They got teared down automatically

# v.3.1.5

- refactored some of the gulp tasks
- fixed a few gulp task issues

# v.3.1.3

- fixed gulp issues

# v.3.1.1

- fixed minor issues
- improved build process

# v.3.0.9
- fixed coverage report issues
- fixed and re-factored how tests works

# v.3.0.7

 - minor fixes
 - fixed issues where flow didn't work as expected
 - fixed bundle issues to cmd, es6 etc
 - updated readme
 - general cleanup

# v.3.0.3

- minor fixes
-

# v.3.0.0

- major rewrite
- gulp added to handle coverage cross-browser. Karma + webpack had a major issue
- fixed issues where coverage lines was reported wrong
- fixed issues with mocha tests server side
- browser tests now require that you open the `test-runner.html` in your browser after you have run `npm run browser`
- added support for Google Closure
- added support for bundling till various formats - es6, commonjs, umd, and Google closure

# v.2.0.20

- improved Travis performance. PhantomJS now used by default
- minor cleanup

# v.2.0.19

- fixed minor webpack config issues
- updated depednencies
- updated readme

# v.2.0.14

- simplified webpack config
- enabled loose mode where available for testing purposes
- added eslint for Rollup bundles

# v.2.0.11

- fixed issues where coverage reported wrong line numbers

# v.2.1.0

- added a few babel minification helpers
   1. auto-remove debugger
   2. auto-remove console.log
   3. transform undefined to void 0
-

# v.2.0.11

- fixed couple of rewire issues ( brucek )
- fixed karma issues

# v.2.0.10

- fixed issue where older nodeJS are not supported anymore

# v.2.0.9

- Fixed issue where coverage reported wrong line numbes

# v.2.0.8

- improved the eslinnt configuration
- minor bug fixes

# v.2.0.7

- Added support for Promise testing with Chai
- Added option for stubbing modules during tests with Rollup

# v.2.0.6

- Fixed rewire issues

# v.2.0.4

- added support for Flow comments. Both parsing and transformation.
- added support for JSX. Only syntax parsing.
- a few bug fixes

# v.2.0.1

- supports stubs, spy, sandbox etc for browser testing (*port 8080*)
- added rewire. Enables options to mock modules for testing purposes
- added support for SinonJS with examples for test doubles
- Typescript support
- improved coverage report support
- added feature for setting environment variables across platforms
- major refactoring
- all dependencies up to date

# v.1.0.0

- stable version

# v.0.9.4

* major refactoring
* added UT testing services
* support for BrowserStack and sauceLab
* package upgrades
* improved how Rollup bundle
* added support for bundle down to ES6 format through
* *jsnext:main*
* improved unit tests the browser - *port 8080*
* improved linting
* use of latest technology
<file_sep>/config/gulp/tasks/lint.js
import gulp from 'gulp';
import eslint from 'gulp-eslint';

// Lint a set of files
function lint(files) {
	return gulp.src(files)
		.pipe(eslint())
		.pipe(eslint.format())
		.pipe(eslint.failAfterError());
}

// Lint our source code
gulp.task('lint:src', () => lint('src/**/*.js'));

// Lint our test code
gulp.task('lint:tests', () => lint('specs/**/*.js'));

// Lint this file
gulp.task('lint:gulp', () => lint('gulpfile.babel.js'));

// Lint everything
gulp.task('lint:all', ['lint:src', 'lint:tests', 'lint:gulp']);
<file_sep>/specs/boily.spec.server.js
describe('Server tests', () => {
	it('should contain 123', () => {
		expect(123).to.equal(123);
	});
});<file_sep>/CONTRIBUTING.md
# Contributing to Boily

Pull requests are very welcome, but should be within the scope of the project, and follow the repository's code conventions. Before submitting a
pull request, it's always good to file an issue, so we can discuss the details of the PR.

## Found an issue?

If you find a bug in the source code or a mistake in the documentation, you can help us by submitting an issue after going through this steps:

1. Ensure you've replicated the issue against master. There is a chance the issue may have already been fixed.

2. Search for any similar issues (both opened and closed). There is a chance someone may have reported it already.

3. Provide a demo of the bug isolated in a jsfiddle/jsbin. Sometimes this is not a possibility, in which case provide a detailed description along
   with any code snippets that would help in triaging the issue. If we cannot reproduce it, we will close it.

4. The best way to demonstrate a bug is to build a failing test. This is not required, however, it will generally speed up the development process.

## Want a feature?

You can request a new feature by submitting an issue . If you would like to implement a new feature then consider what kind of change it is:

**Major Changes** that you wish to contribute to the project should be discussed first on our dev mailing list or IRC so that we can better coordinate our efforts, prevent duplication of work, and help you to craft the change so that it is successfully accepted into the project.
**Small Changes** can be crafted and submitted to the GitHub Repository as a Pull Request.

*Please see the Pull Requests below.*

## Pull Requests

1. At Boily, we have a single Boily Open Source Contributor License Agreement that we ask contributors to electronically sign before merging in their
Pull Requests. Here's the CLA's human-readable summary:

> You are saying that you have the right to give us this code, which is either your own code, or code that your company allows you to publish.
> You want to give us this code. We may decide to use this code. You are not going to sue people who use this code, because, after all,
> you are giving it to an open source project! And if you include code that you didn't write, you'll tell us about it by including the open
> source license to such code in your contribution so we'll know about it. You are not promising that this code works well, or that you
> will support it, and we're OK with that.

2. [Fork](https://github.com/kflash/Boily/fork/) the repository and create your branch from master.

3. Ensure that all tests are passing prior to submitting.

4. If you are adding new functionality, or fixing a bug, provide test coverage.

5. Ensure the test suite passes

6. Make sure your code lints - we've done our best to make sure these rules match our internal linting guidelines.

7. If you've changed APIs, update the documentation.

8. Follow syntax guidelines detailed below.

9. Push the changes to your fork and submit a pull request. If this resolves any issues, please mark in the body resolve #ID within the body of your pull request.
   This allows for github to automatically close the related issue once the pull request is merged.

10. Last step, submit the pull request!

## Style Guide

Our linter will catch most styling issues that may exist in your code. You can check the status of your code styling by simply running: `npm run lint`

However, there are still some styles that the linter cannot pick up. If you are unsure about something, looking at [Airbnb's Style Guide](https://github.com/airbnb/javascript)
will guide you in the right direction.

### Code Conventions

* Use semicolons ;
* 2 spaces for indentation (no tabs)
* Prefer ' over "
* 80 character line length
* Write "attractive" code
* Do not use the optional parameters of setTimeout and setInterval
* Documentation
* Comments
* Unit tests

### Documentation

* Do not wrap lines at 80 characters

## License

By contributing to Boily, you agree that your contributions will be licensed under its MIT license.<file_sep>/specs/boily.spec.browser.js
import boily from '../src/index';

describe( 'General boily tests', () => {

	it('should be a object', () => {
		expect( boily ).to.be.a.object;
	});

	it( 'should contain 123', () => {
		expect( boily.foo ).to.equal( 123 );
	});
});<file_sep>/config/gulp/tasks/build.js
import gulp from 'gulp';
import path from 'path';
import del from 'del';
import source from 'vinyl-source-stream';
import rollup from 'rollup-stream';
import babel from 'rollup-plugin-babel';
import uglify from 'rollup-plugin-uglify';
import buffer from 'vinyl-buffer';
import filesize from 'rollup-plugin-filesize';
import typescript from 'rollup-plugin-typescript';
import stub from 'rollup-plugin-stub';
import nodeResolve from 'rollup-plugin-node-resolve';
import commonjs from 'rollup-plugin-commonjs';
import replace from 'gulp-replace';
import sourcemaps from 'gulp-sourcemaps';
import pack from '../../../package.json';

const env = process.env;
const artifactName = 'boily';
const googModuleName = 'boily';

/*
 * Banner
 **/
const copyright =
	'/*!\n' +
	' * ' + pack.name + ' v' + pack.version + '\n' +
	' * (c) ' + new Date().getFullYear() + ' ' + pack.author.name + '\n' +
	' * Released under the ' + pack.license + ' License.\n' +
	' */';

function clean() {
	return del(['dist/']);
}

function bundle(format) {
	return rollup({
		entry: path.resolve('src/index.js'),
		sourceMap: false,
		banner: copyright,
		plugins: [
			env.min === 'true' ? uglify({
				warnings: false,
				compress: {
					screw_ie8: true,
					dead_code: true,
					unused: true,
					keep_fargs: false,
					drop_debugger: true,
					booleans: true // various optimizations for boolean context, for example !!a ? b : c → a ? b : c
				},
				mangle: {
					screw_ie8: true
				}
			}) : {},
			babel({
				babelrc: false,
				presets: 'es2015-rollup',
				exclude: 'node_modules/**',
				plugins: env.NODE_ENV ? [
					'transform-flow-strip-types',
					'syntax-flow',
					'transform-remove-debugger',
					'transform-remove-console',
					'transform-undefined-to-void',
					'transform-inline-environment-variables',

				] : []
			}),
			nodeResolve({
				jsnext: true,
				main: true
			}),
			commonjs(),
			stub(),
			typescript(),
			filesize(),
			replace({
				'process.env.NODE_ENV': JSON.stringify('production'),
				VERSION: pack.version
			})
		],
		format: format,
		moduleName: 'Boily',
		globals: {
			boily: 'Boily'
		}
	});
}

// Build a production bundle
gulp.task('build:prod', () => {
	env.NODE_ENV = 'production';
	env.min = true;

	return bundle('umd')
		.pipe(source(artifactName + '.min.js'))
		.pipe(buffer())
		.pipe(sourcemaps.init({
			loadMaps: true
		}))
		.pipe(sourcemaps.write('.'))
		.pipe(gulp.dest('dist'));
});

// Build a development bundle
gulp.task('build:dev', () => {
		env.NODE_ENV = 'development';
		env.min = false;

		return bundle('umd')
			.pipe(source(artifactName + '.js'))
			.pipe(buffer())
			.pipe(sourcemaps.init({
				loadMaps: true
			}))
			.pipe(sourcemaps.write('.'))
			.pipe(gulp.dest('dist'));
	}
);

// Build a commonJS bundle
gulp.task('build:common', () => {
	env.NODE_ENV = undefined;
	env.min = false;

	return bundle('cjs')
		.pipe(source(artifactName + '.cjs.js'))
		.pipe(buffer())
		.pipe(sourcemaps.init({
			loadMaps: true
		}))
		.pipe(sourcemaps.write('.'))
		.pipe(gulp.dest('dist'));
});

// Build a ES6 bundle
gulp.task('build:es6', () => {
		return clean()
			.then(() => {
				env.NODE_ENV = undefined;
				env.min = false;

				return bundle('es6')
					.pipe(source(artifactName + '.es2015.js'))
					.pipe(buffer())
					.pipe(sourcemaps.init({
						loadMaps: true
					}))
					.pipe(sourcemaps.write('.'))
					.pipe(gulp.dest('dist'));
			})
	}
);

// Build a closure bundle
gulp.task('build:closure', () => {
	env.NODE_ENV = undefined;
	env.min = false;
	const moduleDeclaration = 'goog.module(\'' + googModuleName + '\');';

	return bundle('cjs')
		.pipe(source(artifactName + '.closure.js'))
		.pipe(buffer())
		.pipe(sourcemaps.init({
			loadMaps: true
		}))
		.pipe(replace(/('|")use strict\1;/, moduleDeclaration))
		.pipe(replace("process.env.NODE_ENV !== 'production'", 'goog.DEBUG'))
		.pipe(sourcemaps.write('.'))
		.pipe(gulp.dest('dist'));
});
<file_sep>/.eslintrc.js
const OFF = 0;
const WARNING = 1;
const ERROR = 2;

module.exports = {
	parser: 'babel-eslint',

	plugins: [],

	'globals': {
		'document': true,
		'window': true,
		'spy': true,
		'mocha': true,
		'stub': true,
		'beforeEach': true,
		'useFakeTimers': true,
		'useFakeXMLHttpRequest': true,
		'useFakeServer': true
	},
	'ecmaFeatures': {
		'jsx': true,
		'modules': true
	},
	'env': {
		'es6': true,
		'browser': true,
		'mocha': true,
		'node': true
	},
	// prevent eslint from taking user's eslint config files that are higher
	// in the directory structure into consideration.
	root:true,
	rules: {
		'accessor-pairs': OFF,
		'brace-style': [ERROR, '1tbs'],
		'comma-dangle': [ERROR],
		'consistent-return': ERROR,
		'dot-location': [ERROR, 'property'],
		'dot-notation': ERROR,
		'eqeqeq': [ERROR, 'allow-null'],
		'indent': [ERROR, 'tab', { 'SwitchCase': 1	}],
		'jsx-quotes': [ERROR, 'prefer-double'],
		'no-cond-assign': [ERROR, 'except-parens'],
		'no-console': 0,
		'no-constant-condition': OFF,
		'no-debugger': WARNING,
		'no-bitwise': OFF,
		'no-multi-spaces': ERROR,
		'no-mixed-spaces-and-tabs': [ ERROR, 'smart-tabs' ],
		'no-restricted-syntax': [ERROR, 'WithStatement'],
		'no-shadow': ERROR,
		'no-unused-vars': [ERROR, {args: 'none'}],
		'no-dupe-keys': ERROR,
		'no-duplicate-case': ERROR,
		'no-empty-character-class': ERROR,
		'no-ex-assign': ERROR,
		'no-extra-semi': ERROR,
		'no-func-assign': ERROR,
		'no-inner-declarations': [ERROR, 'both'],
		'no-invalid-regexp': ERROR,
		'no-irregular-whitespace': ERROR,
		'no-negated-in-lhs': ERROR,
		'no-obj-calls': ERROR,
		'no-regex-spaces': ERROR,
		'no-sparse-arrays': ERROR,
		'no-unreachable': ERROR,
		'no-div-regex': ERROR,
		'no-eq-null': ERROR,
		'no-eval': ERROR,
		'no-return-assign': ERROR,
		'quotes': [ERROR, 'single', 'avoid-escape'],
		'semi-spacing': [ERROR, { 'after': true }],
		'semi': [ERROR, 'always'],
		'space-before-blocks': ERROR,
		'space-before-function-paren': [ERROR, {anonymous: 'never', named: 'never'}],
		'strict': [ERROR, 'global'],
		'keyword-spacing': ERROR,
		'space-infix-ops': ERROR,
		'space-unary-ops': [ERROR, { 'words': true 	}],
		'spaced-comment': [ERROR, 'always', { 'exceptions': ['*'] }],
		'wrap-regex': ERROR,
		'constructor-super': ERROR,
		'no-class-assign': ERROR,
		'no-const-assign': ERROR,
		'no-this-before-super': ERROR,
		'no-var': ERROR,
		'prefer-spread': ERROR
	}
};<file_sep>/config/gulp/index.js
import gulp from 'gulp';
import fs from 'fs';
import onlyScripts from './util/scriptFilter';

const tasks = fs.readdirSync('./config/gulp/tasks/').filter(onlyScripts);

// Ensure process ends after all Gulp tasks are finished
gulp.on('stop', () => {
	if ( !global.isWatching ) {
		process.nextTick(() => {
			process.exit(0);
		});
	}
});

tasks.forEach((task) => {
	require('./tasks/' + task);
});<file_sep>/src/index.js
import boily from './foo';

// Correct version will be set with the 'rollup-replace plugin'
boily.version = 'VERSION';

// Flow example
 function foo(one: any, two: number, three?): string {}

 boily.flow = foo;

export default boily;<file_sep>/config/gulp/tasks/help.js
import gulp from 'gulp';
import taskListing from 'gulp-task-listing';

// List all tasks
gulp.task('help', taskListing.withFilters(/:/));<file_sep>/src/foo.js
export default { foo: 123 };<file_sep>/config/gulp/tasks/watch.js
import gulp from 'gulp';

// Run the headless unit tests as you make changes.
gulp.task('watch:server',() => {
	gulp.watch(['src/**/*', './specs/**/*spec.browser.js', './specs/**/*spec.server.js', 'package.json', '**/.eslintrc'], ['test']);
});<file_sep>/gulpfile.babel.js
// Require all tasks in the 'config/gulp' folder.subfolder
import './config/gulp';<file_sep>/config/setup/browser.js
window.mocha.setup('bdd');
window.onload = function() {
  window.mocha.checkLeaks();
  window.mocha.globals(Object.keys({
	  'expect': true,
	  'mock': true,
	  'sandbox': true,
	  'spy': true,
	  'stub': true,
	  'useFakeServer': true,
	  'useFakeTimers': true,
	  'useFakeXMLHttpRequest': true
  }));
  window.mocha.run();
  require('./setup')(window);
};
<file_sep>/.babelrc
{
    'presets': [
        'es2015'
    ],
    'plugins': [
        'transform-object-rest-spread',
        'transform-flow-strip-types',
        'syntax-flow',
        'transform-remove-debugger',
        'transform-remove-console',
        'transform-undefined-to-void',
        'babel-plugin-rewire',
         'check-es2015-constants'
    ]
}
<file_sep>/README.md
### ES2015 boilerplate for creating libraries with the newest front-end technologies.

[![Build Status](https://travis-ci.org/Kflash/boily.svg?branch=master)](https://travis-ci.org/Kflash/boily)
[![Coverage Status](https://coveralls.io/repos/github/Kflash/boily/badge.svg?branch=master)](https://coveralls.io/github/Kflash/boily?branch=master)
[![npm version](https://badge.fury.io/js/boily.svg)](https://badge.fury.io/js/boily)
[![npm](https://img.shields.io/npm/l/express.svg?style=flat-square)](https://github.com/kflash/boily/blob/master/LICENSE.md)
[![npm downloads](https://img.shields.io/npm/dm/boily.svg)](https://www.npmjs.org/package/boily)

## Features

* [ES6 with Babel](http://babeljs.io/) for ES6 and ES7
* [Webpack](https://webpack.github.io/) for unit tests
* [Rewire](https://github.com/speedskater/babel-plugin-rewire) enables options to mock modules for testing purposes.
* [Rollup](http://rollupjs.org/) for bundling
* [Stub](https://github.com/eventualbuddha/rollup-plugin-stub) let you stub module exports at runtime when bundling with Rollup.
* [Chai as Promised](https://github.com/domenic/chai-as-promised) extends Chai with a fluent language for asserting facts about promises.
* [Eslint](http://eslint.org/) to maintain a consistent code style
* [Typescript](https://github.com/rollup/rollup-plugin-typescript) support with Rollup and JSX
* [Flow](http://flowtype.org/) for quickly find errors in JavaScript applications
* [Karma](http://karma-runner.github.io/0.13/index.html) as the test runner
* [Universal Module Definition (UMD) API](https://github.com/umdjs/umd), which provides compatibility with the most popular script loaders, to the output.
* [Sinon.JS](http://sinonjs.org/) with examples for test doubles
* [Livereload](http://livereload.com/) an implementation of the LiveReload server in Node.js.
* Unit tests written with ES2015 get transpiled on the fly
* Browser tests in the browser
* Node >= 5.x

## Quick start

The only development dependency of this project is [Node.js](https://nodejs.org/en/). So just make sure you have it installed. Then type few commands known to every Node developer...

```js
$ git clone https://github.com/kflash/boily.git
$ cd boily
$ npm install                   # Install Node modules listed in ./package.json
$ npm run build                 # Build a minified and a non-minified version of the library
```

... and boom! You have it all setup for you!

## Workflow

* `npm run build` - Build task that generates both minified and non-minified scripts
* `npm run build:prod` - Build task that generate a minified script
* `npm run build:dev` - Build task that generate a non-minified script
* `npm run build:es6` - Build task that generate and preserves ES6 imports and exports into a ES2015 development bundle
* `npm run build:closure` - Build task that generate a Google Closure bundle
* `npm run build:common` - Build task that generate a CommonJS bundle
* `npm run build:all` - Runs all build tasks
* `npm run lint:source` - Lint the source
* `npm run lint:tests` - Lint the unit tests
* `npm run lint:gulp` - Lint the gulp file
* `npm run lint:all` - Lint everything. Source files, test and the gulp file
* `npm run clean` - Remove the coverage report - and the *dist* folder
* `npm run server:cov` - Run Isparta, a code coverage tool
* `npm run test` - Runs unit tests for both server and the browser
* `npm run test:browser` - Runs the unit tests for browser
* `npm run test:server` - Runs the unit tests on the server
* `npm run karma:chrome` - Runs the unit tests for browser with Chrome
* `npm run karma:phantom` - Runs the unit tests for browser with PhantomJS
* `npm run karma:ie` - Runs the unit tests for browser with Internet Explorer
* `npm run karma:firefox` - Runs the unit tests for browser with Firefox
* `npm run watch:server` - Run all unit tests for server & watch files for changes
* `npm run watch:browser` - Run all unit tests for browser & watch files for changes
* `npm run watch:chrome` - Run all unit tests for browser with Chrome & watch files for changes
* `npm run watch:firefox` - Run all unit tests for browser with Firefox & watch files for changes
* `npm run watch:phantom` - Run all unit tests for browser with PhantomJS & watch files for changes
* `npm run packages` - List installed packages
* `npm run packages:purge` - Remove all dependencies
* `npm run packages:reinstall` - Reinstall all dependencies
* `npm run packages:check` - shows a list over dependencies with a higher version number then the current one - if any
* `npm run packages:upgrade` - Automatically upgrade all devDependencies & dependencies, and update package.json
* `npm run browser` - runs browser unit tests in the browser. All of your unit tests get bundled automatically.

## Testing environment

This project uses Mocha to run your unit tests, it uses Karma as the test runner, it enables the feature that you are able to render your tests to the browser (e.g: Firefox, Chrome etc.).

To add a unit test, simply create a `.spec.browser.js` or a `.spec.server.js` file inside the `~../specs/` folder. Karma will pick up on these files automatically, and Mocha and Chai will be available within your unit tests without the need to import them.

To run unit tests only for the browser ( *client*), or for the server, create either a `~/.spec.browser.js` or `~/spec.server` file inside the same folder.

To run the tests in the project, just simply `npm run test` for both server and client unit tests, or `npm run test:server`. for server or `npm run test:browser`. for browser tests.

To keep watching the common test suites that you are working on, simply do `npm run watch:browser` or `npm run watch:server`.

**Note!** By default all server tests are run with JSDOM

### Adding other test files

- *Browser:*, simply open up the `karma.conf.js` file in the  `~/config` folder and add your files to the `files:` and `preprocessors:` section.
- *NodejS:* open up the `gulpfile.babel.js` file and add your files to the top of the file.

*Note!* Karma runs both browser and nodejs unit tests by default.

## Browser tests

The browser spec runner - `./config.runner.html` - can be opened in a browser to run your tests. For it to work, you must first run `npm run browser`. This will set up a watch task that will
automatically refresh the tests when your scripts, or the tests, change.

### JSX

Only syntax parsing are supported. If you want to transform JSX you need to add a JSX transformer plugins for it. E.g `babel-plugin-transform-react-jsx` for React support.

### Flow

Both parsing and transformation of Flow comments are supported by this boilerplate.

### Rewire

Rewire is supported through the [`babel-plugin-rewire`](https://github.com/speedskater/babel-plugin-rewire) plugin. It is useful for writing tests, specifically to mock the dependencies of the module under test.
Examples and tests are included.

### Sinon

[Sinon.JS](http://sinonjs.org/) is also set up for test doubles - see `BatClass.common.js` for examples of both Sinon and Rewire using ES6 classes.

## Coveralls

This library is set up to integrate with Coveralls, and will automatically publish your coverage report to **coveralls.io** if you have created an account there.

##Rollup

Rollup are used as the library bundler. It bundle down to a cleaner and more lightweight bundle then what you get with for example Webpack and Browserify.

## Package management

Boily has build-in some nice features to always make sure your dependency tree are up to date.

To check for the latest dependencies, simply run `npm run package:check`.

If you want to update your packages, you can simply do `npm run package:upgrade`.

*Note!* Your `package.json` will be automatically updated so make sure you have saved your changes before running this.

To reinstall all packages, do `npm run package:reinstall`, and to remove all packages  `npm run package:purge`.

## Pre-commit

This boilerplate uses a [pre-commit hook](https://www.npmjs.com/package/pre-commit) to ensure that your npm test (or other specified scripts) passes before you can commit your changes. This all conveniently configured in your package.json.

## jsDOM

[jsdom](https://github.com/tmpvar/jsdom) are used to set up React.js components' testing harness under Node.js, based on the amazing jsdom. Also [a couple of bugs](https://github.com/facebook/react/issues/5046) related to React is fixed.

## Linting

ESLint are used to lint your source. To change the rules, edit the .eslintrc file in the root directory, respectively.

## Installation

Download the package, and run this from the command line:

```
npm install
```

## Known issues

- PhantomJS has it's limitation, and doesn't support ES2015 100%. Workaround is too use alternative Karma launcher. E.g. Chrome or Firefox.
- JSDOM have issues with various things that work by default in native DOM. E.g. event listeners get invoked when they shouldn't, and boolean attributes not after the DOM specs.

## Q&A

#### Why isn't rollup used as a preprocessor for Karma?

Simply because Rollup doesn't support rewire. And there is no benefit in using it over Webpack. It could have solved an issue with Webpack and Karma, but the Istanbul
plugin for rollup sucks big time. It's not a issue with the plugin itself.

#### Why use Gulp?

Gulp is used to get the coverage report working cross-browser without issues.

#### Is this backward compatible with Boily 2.x

Yes. Everything works the same.

#### What formats are supported?
commonJS, ES6, UMD, and all other know formats.

#### Is Google Closure supported?
Yes. You can't compile it, but you can bundle your code to output a non-minified Google closure script.

# License

The MIT License (MIT)

Copyright (c) 2016 KFlash

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.

languages:
JSON with Comments
Markdown
JavaScript

repo_language: JSON with Comments

repo_name: Kflash/boily