Set phpBB http status code for deleted sites - http-status-code-301

I need to set the html status codes for a phpBB forum. Google Webmaster Toolkit shows a lot of wrong status codes and this is bad for SEO and for usability.
I've searched a lot but cannot find any appropriate answer. Maybe someone can help me an tell me if theres a way in phpBB or if there's a plugin to achieve this.
The status codes should be different depending on:
User/Thread has been deleted => Status Code "410" (Gone)
Thread has been moved => Status Code "301" (Moved Permanently)
Site can only be seen when logged in => Status Code "403" (Forbidden)

I found a solution, for those who might have the same need, here is the solution.
Reading this PhpBB Tracker issue I found this git commit which lead me to this solution.
Patch the file /path_to_yout_phpbb_forum/includes/functions.php
//line 2618-2637
function send_status_line($code, $message)
{
if (substr(strtolower(#php_sapi_name()),0,3) === 'cgi')
{
// in theory, we shouldn't need that due to php doing it. Reality offers a differing opinion, though
header("Status: $code $message", true, $code);
}
else
{
if (isset($_SERVER['HTTP_VERSION']))
{
$version = $_SERVER['HTTP_VERSION'];
}
else
{
$version = 'HTTP/1.0';
}
header("$version $code $message", true, $code);
}
}
and
//line 3654-3657
if ($msg_text == 'ERROR_NO_ATTACHMENT' || $msg_text == 'NO_FORUM' || $msg_text == 'NO_TOPIC' || $msg_text == 'NO_USER')
{
send_status_line(404, 'Not Found');
}
This worked for my problem.

Related

Chrome extension declarativeNetRequest: get notified on request blocked

The new manifest version 3 of Chrome extension API offers a new function setExtensionActionOptions which allows a typical content blocker to display the number of blocked HTTP requests for a particular tab. The question is: when to call this API? How do I get notified that a request was just blocked and I need to call it with "increment: 1"? I'm looking for the event "onRequestBlocked" or some workaround.
The alarm API is no good because it fires once per minute. Ideally, I'd like to have this number updated in real time, as it is possible with the old MV2.
Another potential solution is to keep the service worker always running which kind of defeats the fruit of moving to MV3 at all.
There's no way to get notification outside of debugging in unpacked mode via onRuleMatchedDebug event.
You can enable automatic display of the number of the blocked requests on the icon badge.
For example, do it when the extension is installed/updated:
chrome.runtime.onInstalled.addListener(() => {
chrome.declarativeNetRequest.setExtensionActionOptions({
displayActionCountAsBadgeText: true,
});
});
You can also provide an explicit increment using tabUpdate property at any time you want:
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => {
if (msg.type === 'block') {
chrome.declarativeNetRequest.setExtensionActionOptions({
tabUpdate: {
tabId: sender.tab.id,
increment: msg.count, // Negative values will decrement the count
},
});
}
});
For future seekers: I've been able to find the following solution
chrome.webRequest.onErrorOccurred.addListener(
(details) => {
chrome.declarativeNetRequest.setExtensionActionOptions({
tabUpdate: {
tabId: details.tabId,
increment: 0
}
});
},
{
urls: ["<all_urls>"]
}
);
Yes, this also counts requests that are blocked by other extensions, but in practice I believe this is not so much of a problem. Another thing that's hard for me to explain, is this increment: 0 parameter. For some reason, the action count is actually incremented by increment + 1, not increment when the tabUpdate argument is provided. So, bizarre enough but works for me quite well this far.

'reloadAction' in Microsoft Bot Framework 3.15 for Node.js is not passing on 'dialogArgs'

I'm following the example from the Bot Framework pages, under 'Handle User Actions' (https://learn.microsoft.com/en-us/azure/bot-service/nodejs/bot-builder-nodejs-dialog-actions?view=azure-bot-service-3.0)
// Order dinner.
bot.dialog('orderDinner', [
function(session, args, next){
if(args && args.isReloaded){
// Reload action was triggered.
}
session.send("Lets order some dinner!");
builder.Prompts.choice(session, "Dinner menu:", dinnerMenu);
}
//...other waterfall steps...
])
// Once triggered, will restart the dialog.
.reloadAction('startOver', 'Ok, starting over.', {
matches: /^start over$/i,
dialogArgs: {
isReloaded: true;
}
});
and after reloading the dialog args.isReloadedis always undefined. That is, it doesn't seem that the framework is passing through what is put in dialogArgs. Any clues as to what I might be missing? I'm using v 3.15 (or rather, the people for whom I'm working are using 3.15) -- was this something that was introduced in a later version 3, that is, after 3.5? Or is something just going wrong?
Any help much appreciated!
Tried the code with the specified version and is working correctly. There is an errant ";" in your code (which is also in the docs) that should be removed and may be the culprit. Change the following line to the below.
Hope of help!
dialogArgs: {
isReloaded: true
}

Avoiding multiple MessageCollectors

I'm making a discord bot with some messageCollector. This messageCollector is created when the bot detects the !Hello command, but if you write again !Hello, another messageCollector is created.
I checked in the discord.js documentation if it's possible to verify if a collector is already open, but I didn't find it.
I thought to make:
if (message === "!Hello") collector.stop("Stopped");
But I don't know if it's the right solution.
Thanks for your help.
You could make a variable that contains a boolean and just make it set to true when someone does !Hello.
let toggled = false;
if (message === "!Hello" && toggled = true) {
return;
} else if (message === "!Hello" && toggled = false) {
toggled = true;
//run the !Hello code here
}
Hope this works, not sure if it's the answer you wanted but this will stop it from creating more messageCollector's.

Detect end of a track's playback with Spotify Web API / Playback SDK

Working with Spotify Web API and Web Playback SDK, does anybody know a good way to detect when a track's playback has finished, i.e. the song is over?
I know about some event named player_state_changed in Web Playback SDK, but the data provided in the event doesn't seem to be very helpful to me.
In my web app, the next song to be played is determined pretty spontaneously. It would be nice, if I could determine it only, when the current track has reached its end. Hence, there is no playlist. Instead, the app plays single tracks in series and should determine the next song, when the current one has ended.
Meanwhile I try it with this code here:
var bCallingNextSong = false;
player.addListener('player_state_changed', state => {
if (state != null &&
state.position == 0 &&
state.duration == 0 &&
state.paused == true) {
if (!bCallingNextSong) {
playNextSong();
}
}
});
function playNextSong() {
$.ajax({
url:"playback.php", //the page containing php script
type: "post", //request type,
dataType: 'json',
data: {action: "next", device: deviceId},
success: function(result) {
bCallingNextSong = false;
},
error: function(XMLHttpRequest, textStatus, errorThrown) {
bCallingNextSong = false;
}
});
}
and in playback.php:
switch ($action) {
case "next":
//some blackbox magic here to determine next song, do logging etc.
//but for now just play the same song over and over
$api->play($deviceId, ['uris' => "spotify:track:0eGsygTp906u18L0Oimnem"],]);
echo json_encode(array("answer"=>"played next"));
break;
// more code
}
However, this will often (but not always) throw an InvalidStateError (I haven't found out where exactly yet nor why). Stack says dequeueUpdates / tryUpdate / _processUpdate / _appendUpdate. Yet, I'm a beginner and I've gotta learn how to cope with Firefox Debugger first.. :)
My last answer got broken so I will now add new solution which work for now.
this.player.addListener('player_state_changed', (state) => {
console.log(state);
if (
this.state
&& state.track_window.previous_tracks.find(x => x.id === state.track_window.current_track.id)
&& !this.state.paused
&& state.paused
) {
console.log('Track ended');
this.setTrackEnd(true);
}
this.state = state;
});
So what is different from last solution? I check that current_track is in previous track list. But there was problem now with position check because it seems that current track appears to previous track list before track is completely end. But that wasn't problem in my app because there is always small delays with commands.
EDIT: This is not working anymore for some reason. Check my other answer which will work now. https://stackoverflow.com/a/51114848/8081009
Here is my solution. It works most of the time. Actually I didn't get it broken in any scenarios I can imagine. So hold last state and check that is it gone to paused state. Hopefully Spotify will ease our work with track ended event. It would be great if they does. This is still better than polling their /me/player/currently-playing endpoint for every 1 second or so.
this.player.addListener(
'player_state_changed',
state =>
{
console.log(state);
if(this.state && !this.state.paused && state.paused && state.position === 0) {
console.log('Track ended');
this.setTrackEnd(true);
}
this.state = state;
}
);
I had this same problem, this is how I solved it.
When a song finish playing it gets added to the state.track_window.previous_tracks list
state.track_window.previous_tracks gets populated only if there is a next track and it starts playing
But every time you call the api to play a new track, it clears the state.track_window.previous_tracks & state.track_window.next_tracks list.
If there is a next track, I want to stop and choose my own next track and then call the api
var alreadyPlayed = state.track_window.previous_tracks
if(alreadyPlayed.length > 0) {
player.pause()
}
if there is no next track the player will be paused when the song finish
if(state.paused && state.position === 0) {
//song ended
ChooseNextSong()
}
the state callback gets fired many times but I want to call ChooseNextSong()
only once, so I increment startCheck every time it fires
if(state.paused && state.position === 0) {
//song ended
startCheck++
if(startCheck === 1) {
ChooseNextSong()
}
}
check if song started
if(state.position === 0 && alreadyPlayed.length === 0 && !state.paused)
{
//song started
startCheck = 0
}
You should use the player_state_changed event and look at which track is playing to see if the track has changed. You can find the current track in playerStateObject.track_window.current_track.
A possible implementation could look like this:
let currentTrack = '';
player.on('player_state_changed', state => {
if( state.track_window.current_track.id != currentTrack ) {
// The track changed!
currentTrack = state.track_window.current_track.id;
}
});

chrome.tabs.executeScript only working with an alert before it

I believe this is related to the asynchronous nature of chrome extensions.
This section of my code:
alert(tab.title);
chrome.tabs.executeScript(tab.id, {code:"document.title = 'test'"});
Works fine, but as soon as I remove the alert, it stops working. Is there anything I can do to remove the alert but still have the js injected?
EDIT: More Code
tabs is a global array of tab objects.
chrome.tabs.onSelectionChanged.addListener(function (tabId) {
for (var i = 0; i < tabs.length; i++) {
if (tabs[i].id == tabId) {
var tab = tabs[i];
while (i < tabs.length) {//length-1
tabs[i] = tabs[i+1];
i++;
}
tabs.pop();
alert(tab.title);//WHY IS THIS NEEDED
chrome.tabs.executeScript(tab.id, {code:"document.title = document.title.substring(1)"});
return;
}
}
});
I am very confused. Changing it the following solves the problem:
chrome.tabs.executeScript(tab.id, {code:"setTimeout('document.title = document.title.substring(1)',100)"});
However, as soon as I change the delay to 50, the script doesn't get executed again. I would prefer not to have to have to make this delay. Does anyone know whats going on?
I know this is an old question, but if anyone is looking - wrap the chrome.tabs.executeScript method in a timeout.
setTimeout(function(){chrome.tabs.executeScript(tab.id, {code:"setTimeout('document.title = document.title.substring(1)',100)"});},500);
It's certainly not ideal but it gets the job done.
Sounds like you have a race condition. My best guess would be to change the injected code to execute on onLoad.

Resources