summarylogtreecommitdiffstats
path: root/wgpp.sh
blob: d2907e6e99aad5b830bbac51c3362905b203e05f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
#!/usr/bin/env bash
# script: wg++ (WebGrab+Plus)
# author: Nikos Toutountzoglou, nikos.toutou@protonmail.com
# rev.date: 2025-03-16

VERSION="5.3.1"

# Variables
WGPP_USR=$(whoami)
WGPP_EXE=$(basename "$0")
WGPP_USR_HOME=$(getent passwd "$WGPP_USR" | cut -d: -f6)
WGPP_CFGDIR="$WGPP_USR_HOME/wg++"
WGPP_SYS="/usr/share/wg++"

# Functions
helpMsg() {
    # Display help message
    cat <<EOF
WebGrab+Plus EPG/XMLTV Grabber v${VERSION}
Usage: $WGPP_EXE [options]

Options:
  -d, --dir <CUSTOM_DIR>   Run from custom configuration folder <CUSTOM_DIR>.
  -g, --generate           Create new configuration folder 'wg++' in user's home directory.
  -u, --update             Update to the latest 'siteini.pack' and channel list files.
  -h, --help               Show this help message.

Examples:
  $WGPP_EXE                       Run using the default configuration directory ($WGPP_USR_HOME/wg++).
  $WGPP_EXE -d <CUSTOM_DIR>       Run using a custom configuration directory.
  $WGPP_EXE -d <CUSTOM_DIR> -g    Create a custom configuration folder.
  $WGPP_EXE -d <CUSTOM_DIR> -u    Update the custom configuration folder.
  $WGPP_EXE -u                    Update the default configuration folder.

EOF
    exit 0
}

checkReq() {
    # Ensure required packages are installed
    local packages=(dotnet libxml2 wget unzip sudo)
    local missing=()
    
    for p in "${packages[@]}"; do
        if ! pacman -Qs "$p" >/dev/null 2>&1; then
            missing+=("$p")
        fi
    done
    
    if [[ ${#missing[@]} -gt 0 ]]; then
        printf "[ critical ] Required package(s) not installed: %s\n" "$(IFS=", "; echo "${missing[*]}")"
        printf "[ info ] Please install with: sudo pacman -S %s\n" "${missing[*]}"
        exit 1
    fi
}

missingSysFiles() {
    # Restore missing system files if needed
    if [[ ! -e "$WGPP_CFGDIR/install.sh" || ! -e "$WGPP_CFGDIR/run.net.sh" ]]; then
        printf "[ info ] Restoring missing script files...\n"
        if ! cp -r -u "$WGPP_SYS"/* "$WGPP_CFGDIR" 2>/dev/null; then
            printf "[ critical ] Failed to restore system files to '%s'\n" "$WGPP_CFGDIR"
            exit 1
        fi
        printf "[ info ] Restored missing script files 'install.sh' and/or 'run.net.sh'.\n"
    fi
}

updateSiteIni() {
    # Update siteini.pack directory or recreate it if missing
    if [[ -d "$WGPP_CFGDIR/siteini.pack" ]]; then
        printf "[ info ] Starting update of '%s/siteini.pack' to the latest release.\n" "$WGPP_CFGDIR"
        cd "$WGPP_CFGDIR/bin.net" || {
            printf "[ critical ] Cannot access '%s/bin.net' directory\n" "$WGPP_CFGDIR"
            exit 1
        }
        
        if ! ./SiteIni.Pack.Update.sh; then
            printf "[ critical ] SiteIni.Pack update failed\n"
            exit 1
        fi
        printf "[ info ] SiteIni.Pack update completed successfully\n"
    else
        printf "[ info ] Cannot find folder 'siteini.pack'. Creating directory...\n"
        if ! mkdir -p "$WGPP_CFGDIR/siteini.pack"; then
            printf "[ critical ] Failed to create directory '%s/siteini.pack'\n" "$WGPP_CFGDIR"
            exit 1
        fi
        printf "[ info ] Please re-run '%s --update' to populate 'siteini.pack'.\n" "$WGPP_EXE"
        exit 1
    fi
}

checkWGPPDir() {
    # Check if the working directory exists
    if [[ ! -d "$WGPP_CFGDIR" ]]; then
        return 1
    fi
    return 0
}

setupCustFolder() {
    if [[ -z "$cust_dir" ]]; then
        printf "[ critical ] Empty custom directory input. Please specify a valid directory.\n" >&2
        exit 1
    fi

    # Resolve the absolute path of the custom directory
    WGPP_CFGDIR=$(realpath "$cust_dir" 2>/dev/null || echo "$cust_dir")

    # Create the directory if it doesn't exist
    if [[ ! -d "$WGPP_CFGDIR" ]]; then
        printf "[ info ] Directory '%s' does not exist. Creating it now...\n" "$WGPP_CFGDIR"
        if ! mkdir -p "$WGPP_CFGDIR"; then
            printf "[ critical ] Failed to create directory '%s'. Please check permissions.\n" "$WGPP_CFGDIR" >&2
            exit 1
        fi
    fi

    printf "[ info ] Using configuration directory: '%s'\n" "$WGPP_CFGDIR"
}

genFolder() {
    # Create a new configuration folder if it doesn't exist
    if [[ ! -d "$WGPP_CFGDIR" ]]; then
        printf "[ info ] Creating new configuration folder '%s'...\n" "$WGPP_CFGDIR"
        if ! cp -r "$WGPP_SYS" "$WGPP_CFGDIR"; then
            printf "[ critical ] Failed to copy system files to '%s'\n" "$WGPP_CFGDIR"
            exit 1
        fi
        
        cd "$WGPP_CFGDIR" || {
            printf "[ critical ] Cannot access '%s' directory\n" "$WGPP_CFGDIR"
            exit 1
        }
        
        if ! sudo -u "$WGPP_USR" ./install.sh; then
            printf "[ critical ] Installation script failed\n"
            exit 1
        fi
        
        printf "[ info ] Configuration folder '%s' created successfully.\n" "$WGPP_CFGDIR"
        printf "[ info ] Configure 'WebGrab++.config.xml' and run '%s' to generate EPG data.\n" "$WGPP_EXE"
        exit 0
    else
        printf "[ info ] Configuration folder '%s' already exists.\n" "$WGPP_CFGDIR"
        printf "[ info ] Use a different directory or delete the existing one first.\n"
        exit 1
    fi
}

runScript() {
    # Execute the main script and ensure output XML is formatted
    cd "$WGPP_CFGDIR" || {
        printf "[ critical ] Cannot access '%s' directory\n" "$WGPP_CFGDIR"
        exit 1
    }
    
    printf "[ info ] Running WebGrab++ from '%s'...\n" "$WGPP_CFGDIR"
    
    # Create temporary file for capturing output
    local tmp_output
    tmp_output=$(mktemp)
    
    # Run the script and capture output
    if ! sudo -u "$WGPP_USR" ./run.net.sh 2>&1 | tee "$tmp_output"; then
        printf "[ critical ] WebGrab++ execution failed\n"
        rm -f "$tmp_output"
        exit 1
    fi
    
    # Check for license-related errors in the output
    if grep -q "Index was outside the bounds of the array" "$tmp_output" || \
       grep -q "Unhandled Exception" "$tmp_output" && \
       grep -q "WGLicense.log.txt" "$tmp_output"; then
        printf "\n[ critical ] WebGrab++ license validation failed\n"
        printf "[ info ] This error typically occurs when no valid license is found or when your license has expired.\n"
        printf "[ info ] Please check the license file in '%s' and ensure it's valid.\n" "$WGPP_CFGDIR"
        
        # If the log file exists, extract relevant license information
        if [[ -f "$WGPP_CFGDIR/WGLicense.log.txt" ]]; then
            printf "\n[ info ] License log information:\n"
            grep -i "license\|exception\|error" "$WGPP_CFGDIR/WGLicense.log.txt" | head -10
            printf "\n[ info ] For full details, see: %s/WGLicense.log.txt\n" "$WGPP_CFGDIR"
        fi
        
        printf "\n[ info ] To obtain a license, visit: https://webgrabplus.com/faq\n"
        rm -f "$tmp_output"
        exit 1
    fi
    
    # Clean up temporary file
    rm -f "$tmp_output"

    if [[ ! -e "$WGPP_CFGDIR/latest.xml" ]]; then
        printf "[ critical ] Missing EPG XML data file 'latest.xml'. Check configuration and logs.\n"
        exit 1
    fi
    
    printf "[ info ] Formatting XML output...\n"
    if ! xmllint --format latest.xml > guide.xml 2>/dev/null; then
        printf "[ warning ] xmllint formatting failed, using unformatted XML\n"
        cp latest.xml guide.xml
    fi
    
    printf "[ info ] EPG data successfully saved as 'guide.xml'.\n"
    exit 0
}

# Argument Parsing with Improvements
cust_dir=""
do_generate=0
do_update=0

while [[ $# -gt 0 ]]; do
    case "$1" in
    -d | --dir)
        if [[ -n "$cust_dir" ]]; then
            printf "[ critical ] The '-d|--dir' option is specified more than once\n" >&2
            exit 1
        fi
        shift
        if [[ $# -eq 0 || "$1" == -* ]]; then
            printf "[ critical ] The '-d|--dir' option requires a directory path argument\n" >&2
            exit 1
        fi
        cust_dir="$1"
        setupCustFolder
        ;;
    -g | --generate)
        do_generate=1
        ;;
    -u | --update)
        do_update=1
        ;;
    -h | --help)
        helpMsg
        ;;
    *)
        printf "[ critical ] Unknown argument '%s'\n" "$1" >&2
        printf "[ info ] Use '%s --help' for usage information\n" "$WGPP_EXE" >&2
        exit 1
        ;;
    esac
    shift
done

# Ensure valid combinations of options
if [[ $do_generate -eq 1 && $do_update -eq 1 ]]; then
    printf "[ critical ] The options '--generate' and '--update' cannot be used together\n" >&2
    exit 1
fi

# Main Execution
checkReq

if [[ $do_generate -eq 1 ]]; then
    genFolder
elif [[ $do_update -eq 1 ]]; then
    if ! checkWGPPDir; then
        printf "[ critical ] Configuration directory '%s' does not exist\n" "$WGPP_CFGDIR"
        printf "[ info ] Use '%s --generate' to create it first, or specify a different directory with -d\n" "$WGPP_EXE"
        exit 1
    fi
    updateSiteIni
else
    # Default execution path (no arguments)
    if ! checkWGPPDir; then
        printf "[ info ] No configuration directory found at '%s'\n" "$WGPP_CFGDIR"
        printf "[ info ] Use '%s --generate' to create a new configuration directory\n" "$WGPP_EXE"
        helpMsg
    fi
    # Directory exists, proceed with normal execution
    missingSysFiles
    runScript
fi

# Script should not reach here, but exit cleanly if it does
exit 0