Merge branch 'dev'
This commit is contained in:
commit
5f6c5425b1
|
@ -82,6 +82,13 @@ func parseCommand(user *gumble.User, username, command string) {
|
|||
} else {
|
||||
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
|
||||
}
|
||||
// Web command
|
||||
case dj.conf.Aliases.WebAlias:
|
||||
if dj.HasPermission(username, dj.conf.Permissions.AdminWeb) {
|
||||
GetWebAddress(user)
|
||||
} else {
|
||||
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
|
||||
}
|
||||
// Move command
|
||||
case dj.conf.Aliases.MoveAlias:
|
||||
if dj.HasPermission(username, dj.conf.Permissions.AdminMove) {
|
||||
|
|
|
@ -86,6 +86,10 @@ HelpAlias = "help"
|
|||
# DEFAULT VALUE: "volume"
|
||||
VolumeAlias = "volume"
|
||||
|
||||
# Alias used for web address command
|
||||
# DEFAULT VALUE: "web"
|
||||
WebAlias = "web"
|
||||
|
||||
# Alias used for move command
|
||||
# DEFAULT VALUE: "move"
|
||||
MoveAlias = "move"
|
||||
|
@ -162,6 +166,10 @@ AdminHelp = false
|
|||
# DEFAULT VALUE: false
|
||||
AdminVolume = false
|
||||
|
||||
# Make web an admin command?
|
||||
# DEFAULT VALUE: false
|
||||
AdminWeb = false
|
||||
|
||||
# Make move an admin command?
|
||||
# DEFAULT VALUE: true
|
||||
AdminMove = true
|
||||
|
|
8
main.go
8
main.go
|
@ -13,9 +13,9 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"os/user"
|
||||
"reflect"
|
||||
"strings"
|
||||
"time"
|
||||
"reflect"
|
||||
|
||||
"github.com/layeh/gopus"
|
||||
"github.com/layeh/gumble/gumble"
|
||||
|
@ -148,8 +148,8 @@ func Verbose(msg string) {
|
|||
}
|
||||
|
||||
func isNil(a interface{}) bool {
|
||||
defer func() { recover() }()
|
||||
return a == nil || reflect.ValueOf(a).IsNil()
|
||||
defer func() { recover() }()
|
||||
return a == nil || reflect.ValueOf(a).IsNil()
|
||||
}
|
||||
|
||||
// dj variable declaration. This is done outside of main() to allow global use.
|
||||
|
@ -230,5 +230,7 @@ func main() {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
Webserver()
|
||||
|
||||
<-dj.keepAlive
|
||||
}
|
||||
|
|
|
@ -51,6 +51,7 @@ type DjConfig struct {
|
|||
NumCachedAlias string
|
||||
CacheSizeAlias string
|
||||
KillAlias string
|
||||
WebAlias string
|
||||
}
|
||||
Permissions struct {
|
||||
AdminsEnabled bool
|
||||
|
@ -70,6 +71,7 @@ type DjConfig struct {
|
|||
AdminNumCached bool
|
||||
AdminCacheSize bool
|
||||
AdminKill bool
|
||||
AdminWeb bool
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -39,8 +39,7 @@ var youtubeVideoPatterns = []string{
|
|||
// YOUTUBE SERVICE
|
||||
// ---------------
|
||||
|
||||
type YouTube struct {
|
||||
}
|
||||
type YouTube struct {}
|
||||
|
||||
// Name of the service
|
||||
func (y YouTube) ServiceName() string {
|
||||
|
@ -405,14 +404,14 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) {
|
|||
}
|
||||
|
||||
// Retrieve items in playlist
|
||||
url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=2&playlistId=%s&key=%s",
|
||||
url = fmt.Sprintf("https://www.googleapis.com/youtube/v3/playlistItems?part=snippet&maxResults=50&playlistId=%s&key=%s",
|
||||
id, os.Getenv("YOUTUBE_API_KEY"))
|
||||
if apiResponse, err = PerformGetRequest(url); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
numVideos, _ := apiResponse.Int("pageInfo", "totalResults")
|
||||
if numVideos > 2 {
|
||||
numVideos = 2
|
||||
if numVideos > 50 {
|
||||
numVideos = 50
|
||||
}
|
||||
|
||||
for i := 0; i < numVideos; i++ {
|
||||
|
|
14
songqueue.go
14
songqueue.go
|
@ -42,14 +42,16 @@ func (q *SongQueue) CurrentSong() Song {
|
|||
|
||||
// NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue.
|
||||
func (q *SongQueue) NextSong() {
|
||||
if s, err := q.PeekNext(); err == nil {
|
||||
if !isNil(q.CurrentSong().Playlist()) && !isNil(s.Playlist()) {
|
||||
if q.CurrentSong().Playlist().ID() != s.Playlist().ID() {
|
||||
q.CurrentSong().Playlist().DeleteSkippers()
|
||||
if !isNil(q.CurrentSong().Playlist()) {
|
||||
if s, err := q.PeekNext(); err == nil {
|
||||
if !isNil(s.Playlist()) {
|
||||
if q.CurrentSong().Playlist().ID() != s.Playlist().ID() {
|
||||
q.CurrentSong().Playlist().DeleteSkippers()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
q.CurrentSong().Playlist().DeleteSkippers()
|
||||
}
|
||||
} else {
|
||||
q.CurrentSong().Playlist().DeleteSkippers()
|
||||
}
|
||||
q.queue = q.queue[1:]
|
||||
}
|
||||
|
|
|
@ -170,3 +170,8 @@ const CURRENT_SONG_HTML = `
|
|||
const CURRENT_SONG_PLAYLIST_HTML = `
|
||||
The song currently playing is "%s", added <b>%s</b> from the playlist "%s".
|
||||
`
|
||||
|
||||
// URL of the server for connecting via a web address
|
||||
const WEB_ADDRESS = `
|
||||
Control mumbledj from a web browser: <a href="http://%s:9563/%s">http://%s:9563/%s</a>
|
||||
`
|
90
web.go
Normal file
90
web.go
Normal file
|
@ -0,0 +1,90 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"math/rand"
|
||||
"net/http"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/layeh/gumble/gumble"
|
||||
)
|
||||
|
||||
var client_token = make(map[string]string)
|
||||
var token_client = make(map[string]string)
|
||||
var external_ip = ""
|
||||
|
||||
type Page struct {
|
||||
Title string
|
||||
Body []byte
|
||||
}
|
||||
|
||||
func (p *Page) save() error {
|
||||
filename := p.Title + ".txt"
|
||||
return ioutil.WriteFile(filename, p.Body, 0600)
|
||||
}
|
||||
|
||||
func loadPage(title string) (*Page, error) {
|
||||
filename := title + ".txt"
|
||||
body, err := ioutil.ReadFile(filename)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Page{Title: title, Body: body}, nil
|
||||
}
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
var uname = token_client[r.URL.Path[1:]]
|
||||
if uname == "" {
|
||||
fmt.Fprintf(w, "I don't know you")
|
||||
} else {
|
||||
fmt.Fprintf(w, "Hi there, I love %s!", uname)
|
||||
}
|
||||
}
|
||||
|
||||
func Webserver() {
|
||||
http.HandleFunc("/", handler)
|
||||
http.ListenAndServe(":9563", nil)
|
||||
rand.Seed(time.Now().UnixNano())
|
||||
}
|
||||
|
||||
func GetWebAddress(user *gumble.User) {
|
||||
if client_token[user.Name] != "" {
|
||||
token_client[client_token[user.Name]] = ""
|
||||
}
|
||||
// dealing with collisions
|
||||
var firstLoop = true
|
||||
for firstLoop || token_client[client_token[user.Name]] != "" {
|
||||
client_token[user.Name] = randSeq(10)
|
||||
firstLoop = false
|
||||
}
|
||||
token_client[client_token[user.Name]] = user.Name
|
||||
dj.SendPrivateMessage(user, fmt.Sprintf(WEB_ADDRESS, getIP(), client_token[user.Name], getIP(), client_token[user.Name]))
|
||||
}
|
||||
|
||||
func getIP() string {
|
||||
if external_ip != "" {
|
||||
return external_ip
|
||||
} else {
|
||||
if response, err := http.Get("http://myexternalip.com/raw"); err == nil {
|
||||
defer response.Body.Close()
|
||||
if response.StatusCode == 200 {
|
||||
if body, err := ioutil.ReadAll(response.Body); err == nil {
|
||||
external_ip = strings.TrimSpace(string(body))
|
||||
}
|
||||
}
|
||||
}
|
||||
return external_ip
|
||||
}
|
||||
}
|
||||
|
||||
var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
|
||||
func randSeq(n int) string {
|
||||
b := make([]rune, n)
|
||||
for i := range b {
|
||||
b[i] = letters[rand.Intn(len(letters))]
|
||||
}
|
||||
return string(b)
|
||||
}
|
Reference in a new issue