Merge branch 'dev'
This commit is contained in:
commit
5f6c5425b1
|
@ -82,6 +82,13 @@ func parseCommand(user *gumble.User, username, command string) {
|
||||||
} else {
|
} else {
|
||||||
dj.SendPrivateMessage(user, NO_PERMISSION_MSG)
|
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
|
// Move command
|
||||||
case dj.conf.Aliases.MoveAlias:
|
case dj.conf.Aliases.MoveAlias:
|
||||||
if dj.HasPermission(username, dj.conf.Permissions.AdminMove) {
|
if dj.HasPermission(username, dj.conf.Permissions.AdminMove) {
|
||||||
|
|
|
@ -86,6 +86,10 @@ HelpAlias = "help"
|
||||||
# DEFAULT VALUE: "volume"
|
# DEFAULT VALUE: "volume"
|
||||||
VolumeAlias = "volume"
|
VolumeAlias = "volume"
|
||||||
|
|
||||||
|
# Alias used for web address command
|
||||||
|
# DEFAULT VALUE: "web"
|
||||||
|
WebAlias = "web"
|
||||||
|
|
||||||
# Alias used for move command
|
# Alias used for move command
|
||||||
# DEFAULT VALUE: "move"
|
# DEFAULT VALUE: "move"
|
||||||
MoveAlias = "move"
|
MoveAlias = "move"
|
||||||
|
@ -162,6 +166,10 @@ AdminHelp = false
|
||||||
# DEFAULT VALUE: false
|
# DEFAULT VALUE: false
|
||||||
AdminVolume = false
|
AdminVolume = false
|
||||||
|
|
||||||
|
# Make web an admin command?
|
||||||
|
# DEFAULT VALUE: false
|
||||||
|
AdminWeb = false
|
||||||
|
|
||||||
# Make move an admin command?
|
# Make move an admin command?
|
||||||
# DEFAULT VALUE: true
|
# DEFAULT VALUE: true
|
||||||
AdminMove = true
|
AdminMove = true
|
||||||
|
|
8
main.go
8
main.go
|
@ -13,9 +13,9 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"os/user"
|
"os/user"
|
||||||
|
"reflect"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
"reflect"
|
|
||||||
|
|
||||||
"github.com/layeh/gopus"
|
"github.com/layeh/gopus"
|
||||||
"github.com/layeh/gumble/gumble"
|
"github.com/layeh/gumble/gumble"
|
||||||
|
@ -148,8 +148,8 @@ func Verbose(msg string) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func isNil(a interface{}) bool {
|
func isNil(a interface{}) bool {
|
||||||
defer func() { recover() }()
|
defer func() { recover() }()
|
||||||
return a == nil || reflect.ValueOf(a).IsNil()
|
return a == nil || reflect.ValueOf(a).IsNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// dj variable declaration. This is done outside of main() to allow global use.
|
// dj variable declaration. This is done outside of main() to allow global use.
|
||||||
|
@ -230,5 +230,7 @@ func main() {
|
||||||
os.Exit(1)
|
os.Exit(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Webserver()
|
||||||
|
|
||||||
<-dj.keepAlive
|
<-dj.keepAlive
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ type DjConfig struct {
|
||||||
NumCachedAlias string
|
NumCachedAlias string
|
||||||
CacheSizeAlias string
|
CacheSizeAlias string
|
||||||
KillAlias string
|
KillAlias string
|
||||||
|
WebAlias string
|
||||||
}
|
}
|
||||||
Permissions struct {
|
Permissions struct {
|
||||||
AdminsEnabled bool
|
AdminsEnabled bool
|
||||||
|
@ -70,6 +71,7 @@ type DjConfig struct {
|
||||||
AdminNumCached bool
|
AdminNumCached bool
|
||||||
AdminCacheSize bool
|
AdminCacheSize bool
|
||||||
AdminKill bool
|
AdminKill bool
|
||||||
|
AdminWeb bool
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,8 +39,7 @@ var youtubeVideoPatterns = []string{
|
||||||
// YOUTUBE SERVICE
|
// YOUTUBE SERVICE
|
||||||
// ---------------
|
// ---------------
|
||||||
|
|
||||||
type YouTube struct {
|
type YouTube struct {}
|
||||||
}
|
|
||||||
|
|
||||||
// Name of the service
|
// Name of the service
|
||||||
func (y YouTube) ServiceName() string {
|
func (y YouTube) ServiceName() string {
|
||||||
|
@ -405,14 +404,14 @@ func NewYouTubePlaylist(user, id string) (*YouTubePlaylist, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Retrieve items in playlist
|
// 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"))
|
id, os.Getenv("YOUTUBE_API_KEY"))
|
||||||
if apiResponse, err = PerformGetRequest(url); err != nil {
|
if apiResponse, err = PerformGetRequest(url); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
numVideos, _ := apiResponse.Int("pageInfo", "totalResults")
|
numVideos, _ := apiResponse.Int("pageInfo", "totalResults")
|
||||||
if numVideos > 2 {
|
if numVideos > 50 {
|
||||||
numVideos = 2
|
numVideos = 50
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := 0; i < numVideos; i++ {
|
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.
|
// NextSong moves to the next Song in SongQueue. NextSong() removes the first Song in the queue.
|
||||||
func (q *SongQueue) NextSong() {
|
func (q *SongQueue) NextSong() {
|
||||||
if s, err := q.PeekNext(); err == nil {
|
if !isNil(q.CurrentSong().Playlist()) {
|
||||||
if !isNil(q.CurrentSong().Playlist()) && !isNil(s.Playlist()) {
|
if s, err := q.PeekNext(); err == nil {
|
||||||
if q.CurrentSong().Playlist().ID() != s.Playlist().ID() {
|
if !isNil(s.Playlist()) {
|
||||||
q.CurrentSong().Playlist().DeleteSkippers()
|
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:]
|
q.queue = q.queue[1:]
|
||||||
}
|
}
|
||||||
|
|
|
@ -170,3 +170,8 @@ const CURRENT_SONG_HTML = `
|
||||||
const CURRENT_SONG_PLAYLIST_HTML = `
|
const CURRENT_SONG_PLAYLIST_HTML = `
|
||||||
The song currently playing is "%s", added <b>%s</b> from the playlist "%s".
|
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