问:
Xamarin. Having trouble correctly implementing AudioManager AudioFocus activity and listeners
I have a media podcast app built with xamarin forms and I am attempting to implement MediaManager's AudioFocus so my app can play well with other media apps. My main issue is being able to call RequestAudioFocus() when the user first clicks play and then also get the listener to work if another app starts playing media while my app is in the background. So both audios are not playing at the same time.

If I stick this code in MainActivity then the request works fine but also I don't really want the request to happen when the user opens the app. I want it to happen when the user clicks play.

I built a notification a while back that pops up a notification when the user first loads an episode that has a play/pause button in there as well that starts an activity to play/pause the episode. If I stick this code in that activity then everything works pretty well, even the listener in regard to other apps interfering. But again, I don't want to request audio focus only when they click the notification outside the app, I want it to start when they also click the play button inside the app.

So now I've built out another activity (different than the notification one). But I don't completely understand yet how to call this activity.  If someone could point me in the right direction that would be great. I've been researching docs and other tutorials but I could use a nudge in the right direction. Thanks for your time.

One of the resources I am using can be found at https://www.sitepoint.com/managing-multiple-sound-sources-in-android-with-audio-focus/

This returns false every time. Doesn't get past the initialization of AudioManager.

```<code> public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void Init(DabPlayer Player, bool IntegrateWithLockScreen)
        {
            dabplayer = Player;
            var mSession = new MediaSessionCompat(Application.Context, "MusicService");
            mSession.SetFlags(MediaSessionCompat.FlagHandlesMediaButtons | MediaSessionCompat.FlagHandlesTransportControls);
            var controller = mSession.Controller;
            var description = GlobalResources.playerPodcast;

            if (IntegrateWithLockScreen)
            {
                /* SET UP LOCK SCREEN */
                CreateNotificationChannel();

                dabplayer.EpisodeDataChanged += (sender, e) =>
                {
                    bool focus = RequestAudioFocus();

                    if (focus)
                    {
                        // Set up an intent so that tapping the notifications returns to this app:
                        Intent intent = new Intent(Application.Context, typeof(MainActivity));
                        Intent playPauseIntent = new Intent(Application.Context, typeof(SecondActivity));
                        //Intent audioFocusIntent = new Intent(Application.Context, typeof(AudioFocusActivity));

                        // Create a PendingIntent;
                        const int pendingIntentId = 0;
                        const int firstPendingIntentId = 1;
                        //const int audioFocusIntentId = 2;
                        //PendingIntent audioFocusPendingIntent =
                        //    PendingIntent.GetActivity(Application.Context, audioFocusIntentId, audioFocusIntent, 0);
                        PendingIntent firstPendingIntent =
                            PendingIntent.GetActivity(Application.Context, firstPendingIntentId, intent, 0);
                        PendingIntent pendingIntent =
                            PendingIntent.GetActivity(Application.Context, pendingIntentId, playPauseIntent, 0);

                        // Build the notification:
                        var builder = new NotificationCompat.Builder(Application.Context, CHANNEL_ID)
                                      .SetStyle(new Android.Support.V4.Media.App.NotificationCompat.MediaStyle()
                                                .SetMediaSession(mSession.SessionToken)
                                                .SetShowActionsInCompactView(0))
                                      .SetVisibility(NotificationCompat.VisibilityPublic)
                                      .SetContentIntent(firstPendingIntent) // Start up this activity when the user clicks the intent.
                                      .SetDeleteIntent(MediaButtonReceiver.BuildMediaButtonPendingIntent(Application.Context, PlaybackState.ActionStop))
                                      .SetSmallIcon(Resource.Drawable.app_icon) // This is the icon to display
                                      .AddAction(Resource.Drawable.ic_media_play_pause, "Play", pendingIntent)
                                      .SetContentText(GlobalResources.playerPodcast.EpisodeTitle)
                                      .SetContentTitle(GlobalResources.playerPodcast.ChannelTitle);

                        // Finally, publish the notification:
                        var notificationManager = NotificationManagerCompat.From(Application.Context);
                        notificationManager.Notify(NOTIFICATION_ID, builder.Build());

                        //StartActivity(audioFocusIntent);  causes trying to invoke virtual method on
                        //null object reference when code and code above is uncommented
                    }
                };

                dabplayer.EpisodeProgressChanged += (object sender, EventArgs e) =>
                {

                };
            }
        }
</code>```

This is the activity that was originally just supposed to be used for the notification area

```<code>[Activity]
    public class SecondActivity :  Activity, AudioManager.IOnAudioFocusChangeListener
    {
        DabPlayer player = GlobalResources.playerPodcast;
        EpisodeViewModel Episode;

        public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void OnAudioFocusChange([GeneratedEnum] AudioFocus focusChange)
        {
            switch (focusChange)
            {
                case AudioFocus.Gain:
                    player.Play();
                    //Gain when other Music Player app releases the audio service
                    break;
                case AudioFocus.Loss:
                    //We have lost focus stop!
                    player.Stop();
                    break;
                case AudioFocus.LossTransient:
                    //We have lost focus for a short time, but likely to resume so pause
                    player.Pause();
                    break;
                case AudioFocus.LossTransientCanDuck:
                    //We have lost focus but should till play at a muted 10% volume
                    //player.SetVolume(.1);
                    break;
            }
        }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            if (player.IsReady)
            {
                if (player.IsPlaying)
                {
                    player.Pause();
                }
                else
                {
                    if (RequestAudioFocus())
                    {
                        player.Play();
                    }
                }
            }
            else
            {
                if (player.Load(Episode.Episode))
                {
                    if (RequestAudioFocus())
                    {
                        player.Play();
                    }
                }
                else
                {
                    //DisplayAlert("Episode Unavailable", "The episode you are attempting to play is currently unavailable. Please try again later.", "OK");
                }

            }

            Finish();
        }
    }
</code>```

This is the new activity I built and hoping to use when the user interacts with the player but I'm not sure how to call/implement it.

```<code>[Activity]
    public class AudioFocusActivity : Activity, AudioManager.IOnAudioFocusChangeListener
    {
        DabPlayer player = GlobalResources.playerPodcast;
        DroidDabNativePlayer droid = new DroidDabNativePlayer();
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            RequestAudioFocus();
        }

        public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void OnAudioFocusChange([GeneratedEnum] AudioFocus focusChange)
        {
            switch (focusChange)
            {
                case AudioFocus.Gain:
                    player.Play();
                    //Gain when other Music Player app releases the audio service
                    break;
                case AudioFocus.Loss:
                    //We have lost focus stop!
                    player.Stop();
                    break;
                case AudioFocus.LossTransient:
                    //We have lost focus for a short time, but likely to resume so pause
                    player.Pause();
                    break;
                case AudioFocus.LossTransientCanDuck:
                    //We have lost focus but should till play at a muted 10% volume
                    //player.SetVolume(.1);
                    break;
            }
        }
    }
</code>```

This is just my play method in my androidplayer class

```<code> /// Begin playback or resume if paused
        public void Play()
        {
            if (player == null)
                return;

            if (IsPlaying)
            {
                //Go back to the beginning (don't start playing)... not sure what this is here for if if it ever gets hit.
                Pause();
                Seek(0);
            }
            else if (player.CurrentPosition >= player.Duration)
            {
                //Start over from the beginning if at the end of the file
                player.Pause();
                Seek(0);
            }
            else
            {
                //Play from where we're at

            }

            player.Start();
        }
</code>```

答:
If I were you I would put both your Audio Focus code and your Audio Player code in a ForegroundService and not the Activity, this way you can navigate to different activities, without interrupting Audio Playback. You will need to do something like that anyways if you want playback when the App is in the background.

Implementing a ForegroundService will also let you add buttons to your notification or if you are using one of the rich Audio Notification, then you can send intents directly to your ForegroundService from the buttons on the notification, rather than having to open up your App. So for your pending intents you could communicate directly with the service instead.

Also when requesting audio focus, you need to respect whether the audio focus was granted or not. Right now you are just requesting it and throwing away the result. Only if the focus was granted you should start playing back the audio.

Body:
I have a media podcast app built with xamarin forms and I am attempting to implement MediaManager's AudioFocus so my app can play well with other media apps. My main issue is being able to call RequestAudioFocus() when the user first clicks play and then also get the listener to work if another app starts playing media while my app is in the background. So both audios are not playing at the same time.

If I stick this code in MainActivity then the request works fine but also I don't really want the request to happen when the user opens the app. I want it to happen when the user clicks play.

I built a notification a while back that pops up a notification when the user first loads an episode that has a play/pause button in there as well that starts an activity to play/pause the episode. If I stick this code in that activity then everything works pretty well, even the listener in regard to other apps interfering. But again, I don't want to request audio focus only when they click the notification outside the app, I want it to start when they also click the play button inside the app.

So now I've built out another activity (different than the notification one). But I don't completely understand yet how to call this activity.  If someone could point me in the right direction that would be great. I've been researching docs and other tutorials but I could use a nudge in the right direction. Thanks for your time.

One of the resources I am using can be found at https://www.sitepoint.com/managing-multiple-sound-sources-in-android-with-audio-focus/

This returns false every time. Doesn't get past the initialization of AudioManager.

 public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void Init(DabPlayer Player, bool IntegrateWithLockScreen)
        {
            dabplayer = Player;
            var mSession = new MediaSessionCompat(Application.Context, "MusicService");
            mSession.SetFlags(MediaSessionCompat.FlagHandlesMediaButtons | MediaSessionCompat.FlagHandlesTransportControls);
            var controller = mSession.Controller;
            var description = GlobalResources.playerPodcast;

            if (IntegrateWithLockScreen)
            {
                /* SET UP LOCK SCREEN */
                CreateNotificationChannel();

                dabplayer.EpisodeDataChanged += (sender, e) =>
                {
                    bool focus = RequestAudioFocus();

                    if (focus)
                    {
                        // Set up an intent so that tapping the notifications returns to this app:
                        Intent intent = new Intent(Application.Context, typeof(MainActivity));
                        Intent playPauseIntent = new Intent(Application.Context, typeof(SecondActivity));
                        //Intent audioFocusIntent = new Intent(Application.Context, typeof(AudioFocusActivity));

                        // Create a PendingIntent;
                        const int pendingIntentId = 0;
                        const int firstPendingIntentId = 1;
                        //const int audioFocusIntentId = 2;
                        //PendingIntent audioFocusPendingIntent =
                        //    PendingIntent.GetActivity(Application.Context, audioFocusIntentId, audioFocusIntent, 0);
                        PendingIntent firstPendingIntent =
                            PendingIntent.GetActivity(Application.Context, firstPendingIntentId, intent, 0);
                        PendingIntent pendingIntent =
                            PendingIntent.GetActivity(Application.Context, pendingIntentId, playPauseIntent, 0);

                        // Build the notification:
                        var builder = new NotificationCompat.Builder(Application.Context, CHANNEL_ID)
                                      .SetStyle(new Android.Support.V4.Media.App.NotificationCompat.MediaStyle()
                                                .SetMediaSession(mSession.SessionToken)
                                                .SetShowActionsInCompactView(0))
                                      .SetVisibility(NotificationCompat.VisibilityPublic)
                                      .SetContentIntent(firstPendingIntent) // Start up this activity when the user clicks the intent.
                                      .SetDeleteIntent(MediaButtonReceiver.BuildMediaButtonPendingIntent(Application.Context, PlaybackState.ActionStop))
                                      .SetSmallIcon(Resource.Drawable.app_icon) // This is the icon to display
                                      .AddAction(Resource.Drawable.ic_media_play_pause, "Play", pendingIntent)
                                      .SetContentText(GlobalResources.playerPodcast.EpisodeTitle)
                                      .SetContentTitle(GlobalResources.playerPodcast.ChannelTitle);

                        // Finally, publish the notification:
                        var notificationManager = NotificationManagerCompat.From(Application.Context);
                        notificationManager.Notify(NOTIFICATION_ID, builder.Build());

                        //StartActivity(audioFocusIntent);  causes trying to invoke virtual method on
                        //null object reference when code and code above is uncommented
                    }
                };

                dabplayer.EpisodeProgressChanged += (object sender, EventArgs e) =>
                {

                };
            }
        }

This is the activity that was originally just supposed to be used for the notification area

[Activity]
    public class SecondActivity :  Activity, AudioManager.IOnAudioFocusChangeListener
    {
        DabPlayer player = GlobalResources.playerPodcast;
        EpisodeViewModel Episode;

        public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void OnAudioFocusChange([GeneratedEnum] AudioFocus focusChange)
        {
            switch (focusChange)
            {
                case AudioFocus.Gain:
                    player.Play();
                    //Gain when other Music Player app releases the audio service
                    break;
                case AudioFocus.Loss:
                    //We have lost focus stop!
                    player.Stop();
                    break;
                case AudioFocus.LossTransient:
                    //We have lost focus for a short time, but likely to resume so pause
                    player.Pause();
                    break;
                case AudioFocus.LossTransientCanDuck:
                    //We have lost focus but should till play at a muted 10% volume
                    //player.SetVolume(.1);
                    break;
            }
        }

        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);

            if (player.IsReady)
            {
                if (player.IsPlaying)
                {
                    player.Pause();
                }
                else
                {
                    if (RequestAudioFocus())
                    {
                        player.Play();
                    }
                }
            }
            else
            {
                if (player.Load(Episode.Episode))
                {
                    if (RequestAudioFocus())
                    {
                        player.Play();
                    }
                }
                else
                {
                    //DisplayAlert("Episode Unavailable", "The episode you are attempting to play is currently unavailable. Please try again later.", "OK");
                }

            }

            Finish();
        }
    }

This is the new activity I built and hoping to use when the user interacts with the player but I'm not sure how to call/implement it.

[Activity]
    public class AudioFocusActivity : Activity, AudioManager.IOnAudioFocusChangeListener
    {
        DabPlayer player = GlobalResources.playerPodcast;
        DroidDabNativePlayer droid = new DroidDabNativePlayer();
        protected override void OnCreate(Bundle bundle)
        {
            base.OnCreate(bundle);
            RequestAudioFocus();
        }

        public bool RequestAudioFocus()
        {
            AudioManager audioManager = (AudioManager)GetSystemService(AudioService);
            AudioFocusRequest audioFocusRequest;
            if (Build.VERSION.SdkInt > BuildVersionCodes.O)
            {
                audioFocusRequest = audioManager.RequestAudioFocus(new AudioFocusRequestClass.Builder(AudioFocus.Gain)
                .SetAudioAttributes(new AudioAttributes.Builder().SetLegacyStreamType(Android.Media.Stream.Music).Build()).SetOnAudioFocusChangeListener(this)
                .Build());
            }
            else
            {
                audioFocusRequest = audioManager.RequestAudioFocus(this, Android.Media.Stream.Music, AudioFocus.Gain);
            }

            if (audioFocusRequest == AudioFocusRequest.Granted)
            {
                return true;
            }
            return false;
        }

        public void OnAudioFocusChange([GeneratedEnum] AudioFocus focusChange)
        {
            switch (focusChange)
            {
                case AudioFocus.Gain:
                    player.Play();
                    //Gain when other Music Player app releases the audio service
                    break;
                case AudioFocus.Loss:
                    //We have lost focus stop!
                    player.Stop();
                    break;
                case AudioFocus.LossTransient:
                    //We have lost focus for a short time, but likely to resume so pause
                    player.Pause();
                    break;
                case AudioFocus.LossTransientCanDuck:
                    //We have lost focus but should till play at a muted 10% volume
                    //player.SetVolume(.1);
                    break;
            }
        }
    }

This is just my play method in my androidplayer class

 /// Begin playback or resume if paused
        public void Play()
        {
            if (player == null)
                return;

            if (IsPlaying)
            {
                //Go back to the beginning (don't start playing)... not sure what this is here for if if it ever gets hit.
                Pause();
                Seek(0);
            }
            else if (player.CurrentPosition >= player.Duration)
            {
                //Start over from the beginning if at the end of the file
                player.Pause();
                Seek(0);
            }
            else
            {
                //Play from where we're at

            }

            player.Start();
        }


来源: stackexchange

问:
How do I fix "Could not connect to remote process" while trying to debug the application?
I am making a android studio project and I try to debug my application.

Running the application works fine, but when I try to debug it I get this error:

Could not connect to remote process. Aborting debug session.

What can I do to fix the issue?

答:
By default Android Studio builds the debug version of the application. However, during the publishing phase you may have switched to the release one as the tutorial suggests.

ADB won't be able to attach to the application unless you revert to the debug configuration or you allow to the debug the release one.

If nothing of this works, you may resort in restarting ADB as explianed in How to restart ADB manually from Android Studio

Revert to debug configuration

Choose Build->Select Build Variant

Pick up debug in the second column

Deploy the application again

Allow the release version to be debugged

Select your application node in the tree

Right click and choose Open Module Settings (or hit F4)

Select Build Variants on the left

Choose release on the right

Set debuggable to true

Apply and deploy the application

Keep in mind that your life won't be easy as your application may be optimized and therefore not debugger friendly (e.g. you might not be able to step in certain methods, or view some local variables).

ContentLicense: CC BY-SA 4.0


问:
How to execute tasks dynamically in Gradle 5?
In gradle 5, the execute() method is removed. What is the quickest way to migrate a gradle 4 tasks. I cannot use dependsOn because execution is dynamic based on e.g. the environmentName or another condition:

```<code>task clearData() {
    doLast {
        if ( environmentName in nonProductionEnvironments ) {
            clearTask1.execute()
            clearTask2.execute()
        } else {
            throw new GradleException("Not allowed to clear data in this environment.")
        }
    }
}
</code>```

答:
I'm not familiar with execute method from tasks, but if it must be dynamic then I suggest adding a listener somewhere depending what you're trying to react to.

There are:

Build listeners: https://docs.gradle.org/current/javadoc/org/gradle/BuildListener.html

Task listeners: https://docs.gradle.org/current/javadoc/org/gradle/api/execution/TaskExecutionGraph.html

There are more, but I believe one of those may solve your issue. Since dependsOn does not work for you, then doing whatever work you're trying to do as a Task does not sound like the right approach.

Body:
In gradle 5, the execute() method is removed. What is the quickest way to migrate a gradle 4 tasks. I cannot use dependsOn because execution is dynamic based on e.g. the environmentName or another condition:

task clearData() {
    doLast {
        if ( environmentName in nonProductionEnvironments ) {
            clearTask1.execute()
            clearTask2.execute()
        } else {
            throw new GradleException("Not allowed to clear data in this environment.")
        }
    }
}


问:
How to export multiple arrays
if I have two arrays how do I export them for example:</p>

```<code>const a=['a','b','c']
const b=['1','2','3']

export default a,b?
</code>```

答:
Try the following while exporting:

```<code>const arr1 = ['a','b','c']
const arr2 = ['1','2','3']
export default { a, b }

</code>```

And while importing

```<code>import { arr1, arr2 } from "path to the file";

//your code
</code>```

Title: How to export multiple arrays

Body:
if I have two arrays how do I export them for example:

const a=['a','b','c']
const b=['1','2','3']

export default a,b?

Body:
Try the following while exporting:

const arr1 = ['a','b','c']
const arr2 = ['1','2','3']
export default { a, b }

And while importing

import { arr1, arr2 } from "path to the file";

//your code


问:
If I assign a procedure to an object property, can it reference other properties of the object?
Best shown with a simple example, question is the ShowMessage at the bottom:

```<code>type
  TFrmSelfRef = class(TForm)
    BtnTest: TButton;
    procedure BtnTestClick(Sender: TObject);
  private
  public
    procedure ExternalCaller;
  end;

type
   TProcType = procedure of Object;

type
   TSomeObj = class
   private
      FIdentifier: Integer;
      FCaller    : TProcType;
   public
      property Caller     : TProcType read FCaller write FCaller;
      property Identifier : integer read FIdentifier write FIdentifier;
   end;

[snip]

procedure TFrmSelfRef.BtnTestClick(Sender: TObject);
var
   lSomeObj: TSomeObj;
begin
   lSomeObj := TSomeObj.Create;
   lSomeObj.Identifier := 200;
   lSomeObj.Caller := ExternalCaller;
   lSomeObj.Caller;
   lSomeObj.Free;
end;

procedure TFrmSelfRef.ExternalCaller;
begin
   ShowMessage('Can I access lSomeObj.Identifier (value:200) here?');
end;
</code>```

Reason: I already have a TSomeObj instance containing all the information Caller would require, but the ExternalCaller references other objects/units that I do not want to link (the unit containing) TSomeObj to.

答:
No, that's not possible.

Although ExternalCaller is a method -- and TProcType is a method type ("of object") -- the hidden Self parameter for ExternalCaller() refers to the TFrmSelfRef object that creates lSomeObj; it does not refer to lSomeObj.

Also, you probably already know this, but never write

```<code>lSomeObj := TSomeObj.Create;
lSomeObj.Identifier := 200;
lSomeObj.Caller := ExternalCaller;
lSomeObj.Caller;
lSomeObj.Free;
</code>```

Instead, write

```<code>lSomeObj := TSomeObj.Create;
try
  lSomeObj.Identifier := 200;
  lSomeObj.Caller := ExternalCaller;
  lSomeObj.Caller;
finally
  lSomeObj.Free;
end;
</code>```

If an exception occurs (or you leave by using Exit or Break or Continue) -- as is normal in Delphi -- you mustn't leak memory and other resources! Always use try..finally to protect resources.

Body:
Best shown with a simple example, question is the ShowMessage at the bottom:

type
  TFrmSelfRef = class(TForm)
    BtnTest: TButton;
    procedure BtnTestClick(Sender: TObject);
  private
  public
    procedure ExternalCaller;
  end;

type
   TProcType = procedure of Object;

type
   TSomeObj = class
   private
      FIdentifier: Integer;
      FCaller    : TProcType;
   public
      property Caller     : TProcType read FCaller write FCaller;
      property Identifier : integer read FIdentifier write FIdentifier;
   end;

[snip]

procedure TFrmSelfRef.BtnTestClick(Sender: TObject);
var
   lSomeObj: TSomeObj;
begin
   lSomeObj := TSomeObj.Create;
   lSomeObj.Identifier := 200;
   lSomeObj.Caller := ExternalCaller;
   lSomeObj.Caller;
   lSomeObj.Free;
end;

procedure TFrmSelfRef.ExternalCaller;
begin
   ShowMessage('Can I access lSomeObj.Identifier (value:200) here?');
end;

Reason: I already have a TSomeObj instance containing all the information Caller would require, but the ExternalCaller references other objects/units that I do not want to link (the unit containing) TSomeObj to.

Body:
No, that's not possible.

Although ExternalCaller is a method -- and TProcType is a method type ("of object") -- the hidden Self parameter for ExternalCaller() refers to the TFrmSelfRef object that creates lSomeObj; it does not refer to lSomeObj.

Also, you probably already know this, but never write

lSomeObj := TSomeObj.Create;
lSomeObj.Identifier := 200;
lSomeObj.Caller := ExternalCaller;
lSomeObj.Caller;
lSomeObj.Free;

Instead, write

lSomeObj := TSomeObj.Create;
try
  lSomeObj.Identifier := 200;
  lSomeObj.Caller := ExternalCaller;
  lSomeObj.Caller;
finally
  lSomeObj.Free;
end;

If an exception occurs (or you leave by using Exit or Break or Continue) -- as is normal in Delphi -- you mustn't leak memory and other resources! Always use try..finally to protect resources.


问:
Is there third party package repository for Swift?
I came from web development/design (still are) and I started to learn Swift 5 for iOS app development. In web development, there's a lot of sites or repo where I can download pre-written codes for the web like packagist.org. My question is, is there a similar site where I can pull pre-written code in Swift so I can extend the functionality of an iOS app? Thank you!</p>

答: Here you can use cocoapods, spm </p>

Body: Here you can use cocoapods, spm


问:
Mapping JPA Entity with result of native query
I'm using Spring Data JPA to map entities and tables.

In my PostgreSQL DB, I have a table called declared_location, that stores locations with long and lat. I wrote a sql native query with postgre specific syntax in order to retrieve a list of declared_location, ordered by the relative distance to a given point :

  @Query(value="select *, 1.60934 * (point (:longRef, :latRef) <@> point (longitude, latitude)) as distance from declared_location order by distance", nativeQuery = true)
    List<DeclaredLocation> findAllSortedByDistance(@Param("longRef") double longRef, @Param("latRef") double latRef);

```

<p>I'd like to map the distance calculated by Postgre (column "distance") to a field of my entity. That's where i'm stuck. Here is my entity: </p>

<pre class="lang-java prettyprint-override"><code>@Entity
public class DeclaredLocation {

    @Id
    @Type(type = "uuid-char")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    private double latitude;

    private double longitude;

    private String address;

    @Column
    private Double relativeDistanceKm;

(...)
}
</code>```

How should I tell Spring Data JPA to map the column distance created by postgre as a result of the native query to the field relativeDistanceKm of the entity? What is the right approach to do this?

答:
You can use hibernate @Formula for this purpose.

@Entity
public class DeclaredLocation {
   // ...

   @Formula(value = "1.60934 * (point (13,52) <@> point (longitude, latitude))")
   private Double relativeDistanceKm;
}
```

Body:
I'm using Spring Data JPA to map entities and tables.

In my PostgreSQL DB, I have a table called declared_location, that stores locations with long and lat. I wrote a sql native query with postgre specific syntax in order to retrieve a list of declared_location, ordered by the relative distance to a given point :

  @Query(value="select *, 1.60934 * (point (:longRef, :latRef) <@> point (longitude, latitude)) as distance from declared_location order by distance", nativeQuery = true)
    List<DeclaredLocation> findAllSortedByDistance(@Param("longRef") double longRef, @Param("latRef") double latRef);

I'd like to map the distance calculated by Postgre (column "distance") to a field of my entity. That's where i'm stuck. Here is my entity:

@Entity
public class DeclaredLocation {

    @Id
    @Type(type = "uuid-char")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private UUID id;

    private double latitude;

    private double longitude;

    private String address;

    @Column
    private Double relativeDistanceKm;

(...)
}

How should I tell Spring Data JPA to map the column distance created by postgre as a result of the native query to the field relativeDistanceKm of the entity? What is the right approach to do this?


问:
Magento + Varnish/ReverseProxy + Apache + DirectAdmin causes NET::ERR_CERT_AUTHORITY_INVALID or ERR_TOO_MANY_REDIRECTS
I'm trying to set up a Varnish Cache for Magento using reverse proxy (on Apache) to get https cached. I can't get it to work. So far I've got ERR_TOO_MANY_REDIRECTS and NET::ERR_CERT_AUTHORITY_INVALID while setting up reverse proxy (and 503 when trying to set up Varnish cache to respond directly on http/80).

Technology stack is as follows:

Dedicated server (insane specs)

Centos

Apache

Direct Admin (yeah, I know)

Magento

My understanding of Varnish Cache is as follows:

HTTP: User->Varnish[:80]->Apache[:8080]

HTTPS: User->Apache[:443]->Varnish[:80]->Apache[:8080] (reverse proxy).

Magento settings are as follow:

```<code>web/seo/use_rewrites - 1
web/unsecure/base_url - https://www.{domain}.com/  //Previously it didn't work when I set this up with http. That's why it's https. Tested with http and no difference now.
web/unsecure/base_link_url - {{unsecure_base_url}}
web/unsecure/base_static_url -
web/unsecure/base_media_url -
web/secure/base_url - https://www.{domain}.com/
web/secure/use_in_frontend - 1  //tested 0, no difference
web/secure/use_in_adminhtml - 1 //tested 0, no difference
web/secure/base_link_url - {{secure_base_url}}
web/secure/base_static_url -
web/secure/base_media_url -
web/secure/offloader_header - SSL_OFFLOADED
web/url/use_store - 0
web/url/redirect_to_base - 1 //tested 0, infinite loading
web/default/front - cms
web/default/cms_home_page - home
web/default/no_route - cms/noroute/index
web/default/cms_no_route - no-route
web/default/cms_no_cookies - enable-cookies
web/default/show_cms_breadcrumbs - 1
web/cookie/cookie_lifetime - 3600
web/cookie/cookie_path -
web/cookie/cookie_domain -
web/cookie/cookie_httponly - 0
web/cookie/cookie_restriction - 0
web/session/use_remote_addr - 0
web/session/use_http_via - 0
web/session/use_http_x_forwarded_for - 0
web/session/use_http_user_agent - 0
web/session/use_frontend_sid - 1
web/browser_capabilities/cookies - 1
web/browser_capabilities/javascript - 1
web/browser_capabilities/local_storage - 0
web/default_layouts/default_product_layout -
web/default_layouts/default_category_layout -
web/default_layouts/default_cms_layout - 1column
</code>```

httpd.conf:

```<code>    ServerRoot "/etc/httpd"
    Listen 8080
    <IfModule unixd_module>
    User apache
    Group apache
    </IfModule>
    LoadModule php7_module        /usr/lib/apache/libphp7.so
    Include /etc/httpd/conf/extra/httpd-phpmodules.conf
    DocumentRoot "/home/admin/domains/{domain}.com/public_html"
    <IfModule dir_module>
        Include /etc/httpd/conf/extra/httpd-directoryindex.conf
    </IfModule>
    <Files ".ht*">
        Require all denied
    </Files>
    <Files ".user.ini">
        Require all denied
    </Files>
    LogLevel warn

    <IfModule log_config_module>
        #replace %b with %O for more accurate logging
        <IfModule mod_logio.c>
          LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
          LogFormat "%a %l %u %t \"%r\" %>s %O" common
          LogFormat "%O %I" bytes

          LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
        </IfModule>

        CustomLog /var/log/httpd/access_log common
    </IfModule>

    <IfModule alias_module>
        # Include some DirectAdmin alias
        Include conf/extra/httpd-alias.conf
    </IfModule>
    <IfModule mime_module>
        TypesConfig conf/mime.types
    AddType application/x-gzip .tgz
    AddEncoding x-compress .Z
    AddEncoding x-gzip .gz .tgz
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddHandler cgi-script .cgi
    AddHandler type-map var
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
        AddType video/x-ms-asf .avi
        AddType video/mpeg .mpg
        AddType video/mpeg .mpeg
        AddType video/quicktime .mov
        AddType video/x-ms-wmv .wmv
    </IfModule>

    incldes x20
    Include conf/extra/directadmin-vhosts.conf
    <IfModule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    </IfModule>

!!!-----------------------------And here comes DirectAdmin httpd.conf:----------------------------!!!

[root@  ~]# cat /usr/local/directadmin/data/users/admin/httpd.conf
<Directory "/home/admin/public_html">
        <IfModule mod_ruid2.c>
                RMode config
                RUidGid admin admin
                #RGroups apache access
                RGroups @none
        </IfModule>
        <IfModule mod_fcgid.c>
                SuexecUserGroup admin admin
        </IfModule>
                php_admin_flag engine ON
                php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
                php_admin_value mail.log /home/admin/.php/php-mail.log
                php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
</Directory>

<VirtualHost {ip}:8080 >
        ServerName www.{domain}.com
#        ServerAlias www.{domain}.com {domain}.com //tested "on" - see errors
        ServerAdmin webmaster@{domain}.com
        DocumentRoot /home/admin/domains/{domain}.com/public_html
#        UseCanonicalName OFF //tested uncommenting - see errors
        <IfModule !mod_ruid2.c>
                SuexecUserGroup admin admin
        </IfModule>
        <IfModule mod_ruid2.c>
                RMode config
                RUidGid admin admin
                #RGroups apache access
                RGroups @none
        </IfModule>
        CustomLog /var/log/httpd/domains/{domain}.com.bytes bytes
        CustomLog /var/log/httpd/domains/{domain}.com.log combined
        ErrorLog /var/log/httpd/domains/{domain}.com.error.log
        <Directory /home/admin/domains/{domain}.com/public_html>
                AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,IncludesNOEXEC,MultiViews,SymLinksIfOwnerMatch,FollowSymLinks,None
                Options -ExecCGI -Includes +IncludesNOEXEC
                php_admin_flag engine ON
                php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
                php_admin_value mail.log /home/admin/.php/php-mail.log
                php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
        </Directory>
</VirtualHost>

<VirtualHost {ip}:443 >
        SSLEngine on
        SSLCertificateFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.cert.combined
        SSLCertificateKeyFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.key
        SSLCACertificateFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.cacert
        ServerName www.{domain}.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:80/
    ProxyPassReverse / http://127.0.0.1:80/

    RequestHeader set X-Forwarded-Port "443"
    RequestHeader set X-Forwarded-Proto "https"

        ServerAlias www.{domain}.com {domain}.com
#       ServerAdmin webmaster@{domain}.com
        DocumentRoot /home/admin/domains/{domain}.com/private_html
#       UseCanonicalName OFF
#       <IfModule !mod_ruid2.c>
#               SuexecUserGroup admin admin
#       </IfModule>
#       <IfModule mod_ruid2.c>
#               RMode config
#               RUidGid admin admin
#               #RGroups apache access
#               RGroups @none
#       </IfModule>
        CustomLog /var/log/httpd/domains/{domain}.com.bytes bytes
        CustomLog /var/log/httpd/domains/{domain}.com.log combined
        ErrorLog /var/log/httpd/domains/{domain}.com.error.log
#       <Directory /home/admin/domains/{domain}.com/private_html>
#               AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,IncludesNOEXEC,MultiViews,SymLinksIfOwnerMatch,FollowSymLinks,None
#               Options -ExecCGI -Includes +IncludesNOEXEC
#               php_admin_flag engine ON
#               php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
#               php_admin_value mail.log /home/admin/.php/php-mail.log
#               php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
#       </Directory>
</VirtualHost>
</code>```

PLEASE NOTE: I just want to get this to work, I will transfer all the changes to a seperate file that will not get overwritten by DA.

netstat:

```<code>[root@  ~]# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      3037/named
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 127.0.0.1:6082          0.0.0.0:*               LISTEN      19248/varnishd
tcp        0      0 0.0.0.0:995             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:587             0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd
***tcp     0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      19248/varnishd
tcp        0      0 0.0.0.0:465             0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 {ip}:53                 0.0.0.0:*               LISTEN      3037/named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      3037/named
tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN      2226/pure-ftpd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2201/sshd
tcp6       0      0 ::1:953                 :::*                    LISTEN      3037/named
***tcp6    0      0 :::443                  :::*                    LISTEN      19143/httpd
tcp6       0      0 :::3306                 :::*                    LISTEN      2860/mysqld
tcp6       0      0 :::2222                 :::*                    LISTEN      19694/directadmin
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd
***tcp6    0      0 :::80                   :::*                    LISTEN      19248/varnishd
***tcp6    0      0 :::8080                 :::*                    LISTEN      19143/httpd
tcp6       0      0 :::53                   :::*                    LISTEN      3037/named
tcp6       0      0 :::21                   :::*                    LISTEN      2226/pure-ftpd
tcp6       0      0 :::22                   :::*                    LISTEN      2201/sshd
udp        0      0 {ip}:53                 0.0.0.0:*                           3037/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           3037/named
udp        0      0 0.0.0.0:111             0.0.0.0:*                           1/systemd
udp        0      0 127.0.0.1:323           0.0.0.0:*                           1341/chronyd
udp        0      0 0.0.0.0:659             0.0.0.0:*                           1356/rpcbind
udp6       0      0 :::53                   :::*                                3037/named
udp6       0      0 :::111                  :::*                                1/systemd
udp6       0      0 ::1:323                 :::*                                1341/chronyd
udp6       0      0 :::659                  :::*                                1356/rpcbind

</code>```

Now the problems (with above settings):

https://{domain}.com/ causes NET::ERR_CERT_AUTHORITY_INVALID

https://www.{domain}.com/ causes ERR_TOO_MANY_REDIRECTS

https://{domain}.com/test.php causes NET::ERR_CERT_AUTHORITY_INVALID

https://www.{domain}.com/test.php works fine (tho not served by Varnish)

with server alias on:

https://{domain}.com/ infinite loading

https://www.{domain}.com/ infinite loading

https://{domain}.com/test.php works fine (tho not served by Varnish)

https://www.{domain}.com/test.php works fine (tho not served by Varnish)

I don't think it makes sense to paste every single combination of settings and errors thus I would like to ask you if you can see where the problem might be (other than the use of DA).

Since I think that it is before it gets to varnish.params and varnish.vcl I didn't paste those files. I somewhat suspect .htaccess but you will tell me what other files I should paste.

答:
I noticed you do set RequestHeader set X-Forwarded-Proto "https" in your Apache configuration in the port 443 vhost.

This should announce to your backend that although the connection is done in plain HTTP, it was originally terminated as an HTTPS connection.

Currently your Magento configuration uses SSL_OFFLOADED as the ofloading header, however your Apache config uses X-Forwarded-Proto.

Can you try updating your Magento config as follows?

web/secure/offloader_header - X-FORWARDED-PROTO

This should help Magento look for the right header and realize it doesn't need to redirect back to HTTPS, since the page was already terminated as HTTPS.

Body:
I'm trying to set up a Varnish Cache for Magento using reverse proxy (on Apache) to get https cached. I can't get it to work. So far I've got ERR_TOO_MANY_REDIRECTS and NET::ERR_CERT_AUTHORITY_INVALID while setting up reverse proxy (and 503 when trying to set up Varnish cache to respond directly on http/80).

Technology stack is as follows:

Dedicated server (insane specs)

Centos

Apache

Direct Admin (yeah, I know)

Magento

My understanding of Varnish Cache is as follows:

HTTP: User->Varnish[:80]->Apache[:8080]

HTTPS: User->Apache[:443]->Varnish[:80]->Apache[:8080] (reverse proxy).

Magento settings are as follow:

web/seo/use_rewrites - 1
web/unsecure/base_url - https://www.{domain}.com/  //Previously it didn't work when I set this up with http. That's why it's https. Tested with http and no difference now.
web/unsecure/base_link_url - {{unsecure_base_url}}
web/unsecure/base_static_url -
web/unsecure/base_media_url -
web/secure/base_url - https://www.{domain}.com/
web/secure/use_in_frontend - 1  //tested 0, no difference
web/secure/use_in_adminhtml - 1 //tested 0, no difference
web/secure/base_link_url - {{secure_base_url}}
web/secure/base_static_url -
web/secure/base_media_url -
web/secure/offloader_header - SSL_OFFLOADED
web/url/use_store - 0
web/url/redirect_to_base - 1 //tested 0, infinite loading
web/default/front - cms
web/default/cms_home_page - home
web/default/no_route - cms/noroute/index
web/default/cms_no_route - no-route
web/default/cms_no_cookies - enable-cookies
web/default/show_cms_breadcrumbs - 1
web/cookie/cookie_lifetime - 3600
web/cookie/cookie_path -
web/cookie/cookie_domain -
web/cookie/cookie_httponly - 0
web/cookie/cookie_restriction - 0
web/session/use_remote_addr - 0
web/session/use_http_via - 0
web/session/use_http_x_forwarded_for - 0
web/session/use_http_user_agent - 0
web/session/use_frontend_sid - 1
web/browser_capabilities/cookies - 1
web/browser_capabilities/javascript - 1
web/browser_capabilities/local_storage - 0
web/default_layouts/default_product_layout -
web/default_layouts/default_category_layout -
web/default_layouts/default_cms_layout - 1column

httpd.conf:

    ServerRoot "/etc/httpd"
    Listen 8080
    <IfModule unixd_module>
    User apache
    Group apache
    </IfModule>
    LoadModule php7_module        /usr/lib/apache/libphp7.so
    Include /etc/httpd/conf/extra/httpd-phpmodules.conf
    DocumentRoot "/home/admin/domains/{domain}.com/public_html"
    <IfModule dir_module>
        Include /etc/httpd/conf/extra/httpd-directoryindex.conf
    </IfModule>
    <Files ".ht*">
        Require all denied
    </Files>
    <Files ".user.ini">
        Require all denied
    </Files>
    LogLevel warn

    <IfModule log_config_module>
        #replace %b with %O for more accurate logging
        <IfModule mod_logio.c>
          LogFormat "%a %l %u %t \"%r\" %>s %O \"%{Referer}i\" \"%{User-Agent}i\"" combined
          LogFormat "%a %l %u %t \"%r\" %>s %O" common
          LogFormat "%O %I" bytes

          LogFormat "%a %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\" %I %O" combinedio
        </IfModule>

        CustomLog /var/log/httpd/access_log common
    </IfModule>

    <IfModule alias_module>
        # Include some DirectAdmin alias
        Include conf/extra/httpd-alias.conf
    </IfModule>
    <IfModule mime_module>
        TypesConfig conf/mime.types
    AddType application/x-gzip .tgz
    AddEncoding x-compress .Z
    AddEncoding x-gzip .gz .tgz
    AddType application/x-compress .Z
    AddType application/x-gzip .gz .tgz
    AddHandler cgi-script .cgi
    AddHandler type-map var
    AddType text/html .shtml
    AddOutputFilter INCLUDES .shtml
        AddType video/x-ms-asf .avi
        AddType video/mpeg .mpg
        AddType video/mpeg .mpeg
        AddType video/quicktime .mov
        AddType video/x-ms-wmv .wmv
    </IfModule>

    incldes x20
    Include conf/extra/directadmin-vhosts.conf
    <IfModule ssl_module>
    SSLRandomSeed startup builtin
    SSLRandomSeed connect builtin
    </IfModule>

!!!-----------------------------And here comes DirectAdmin httpd.conf:----------------------------!!!

[root@  ~]# cat /usr/local/directadmin/data/users/admin/httpd.conf
<Directory "/home/admin/public_html">
        <IfModule mod_ruid2.c>
                RMode config
                RUidGid admin admin
                #RGroups apache access
                RGroups @none
        </IfModule>
        <IfModule mod_fcgid.c>
                SuexecUserGroup admin admin
        </IfModule>
                php_admin_flag engine ON
                php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
                php_admin_value mail.log /home/admin/.php/php-mail.log
                php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
</Directory>

<VirtualHost {ip}:8080 >
        ServerName www.{domain}.com
#        ServerAlias www.{domain}.com {domain}.com //tested "on" - see errors
        ServerAdmin webmaster@{domain}.com
        DocumentRoot /home/admin/domains/{domain}.com/public_html
#        UseCanonicalName OFF //tested uncommenting - see errors
        <IfModule !mod_ruid2.c>
                SuexecUserGroup admin admin
        </IfModule>
        <IfModule mod_ruid2.c>
                RMode config
                RUidGid admin admin
                #RGroups apache access
                RGroups @none
        </IfModule>
        CustomLog /var/log/httpd/domains/{domain}.com.bytes bytes
        CustomLog /var/log/httpd/domains/{domain}.com.log combined
        ErrorLog /var/log/httpd/domains/{domain}.com.error.log
        <Directory /home/admin/domains/{domain}.com/public_html>
                AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,IncludesNOEXEC,MultiViews,SymLinksIfOwnerMatch,FollowSymLinks,None
                Options -ExecCGI -Includes +IncludesNOEXEC
                php_admin_flag engine ON
                php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
                php_admin_value mail.log /home/admin/.php/php-mail.log
                php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
        </Directory>
</VirtualHost>

<VirtualHost {ip}:443 >
        SSLEngine on
        SSLCertificateFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.cert.combined
        SSLCertificateKeyFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.key
        SSLCACertificateFile /usr/local/directadmin/data/users/admin/domains/{domain}.com.cacert
        ServerName www.{domain}.com

    ProxyPreserveHost On
    ProxyPass / http://127.0.0.1:80/
    ProxyPassReverse / http://127.0.0.1:80/

    RequestHeader set X-Forwarded-Port "443"
    RequestHeader set X-Forwarded-Proto "https"

        ServerAlias www.{domain}.com {domain}.com
#       ServerAdmin webmaster@{domain}.com
        DocumentRoot /home/admin/domains/{domain}.com/private_html
#       UseCanonicalName OFF
#       <IfModule !mod_ruid2.c>
#               SuexecUserGroup admin admin
#       </IfModule>
#       <IfModule mod_ruid2.c>
#               RMode config
#               RUidGid admin admin
#               #RGroups apache access
#               RGroups @none
#       </IfModule>
        CustomLog /var/log/httpd/domains/{domain}.com.bytes bytes
        CustomLog /var/log/httpd/domains/{domain}.com.log combined
        ErrorLog /var/log/httpd/domains/{domain}.com.error.log
#       <Directory /home/admin/domains/{domain}.com/private_html>
#               AllowOverride AuthConfig FileInfo Indexes Limit Options=Indexes,IncludesNOEXEC,MultiViews,SymLinksIfOwnerMatch,FollowSymLinks,None
#               Options -ExecCGI -Includes +IncludesNOEXEC
#               php_admin_flag engine ON
#               php_admin_value sendmail_path '/usr/sbin/sendmail -t -i -f admin@{domain}.com'
#               php_admin_value mail.log /home/admin/.php/php-mail.log
#               php_admin_value open_basedir /home/admin/:/tmp:/var/tmp:/opt/alt/php72/usr/share/pear/:/dev/urandom:/usr/local/lib/php/:/usr/local/php72/lib/php/
#       </Directory>
</VirtualHost>

PLEASE NOTE: I just want to get this to work, I will transfer all the changes to a seperate file that will not get overwritten by DA.

netstat:

[root@  ~]# netstat -tulpn
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name
tcp        0      0 127.0.0.1:953           0.0.0.0:*               LISTEN      3037/named
tcp        0      0 0.0.0.0:25              0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 0.0.0.0:993             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 127.0.0.1:6082          0.0.0.0:*               LISTEN      19248/varnishd
tcp        0      0 0.0.0.0:995             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:587             0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 0.0.0.0:110             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:143             0.0.0.0:*               LISTEN      2208/dovecot
tcp        0      0 0.0.0.0:111             0.0.0.0:*               LISTEN      1/systemd
***tcp     0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      19248/varnishd
tcp        0      0 0.0.0.0:465             0.0.0.0:*               LISTEN      2203/exim
tcp        0      0 {ip}:53                 0.0.0.0:*               LISTEN      3037/named
tcp        0      0 127.0.0.1:53            0.0.0.0:*               LISTEN      3037/named
tcp        0      0 0.0.0.0:21              0.0.0.0:*               LISTEN      2226/pure-ftpd
tcp        0      0 0.0.0.0:22              0.0.0.0:*               LISTEN      2201/sshd
tcp6       0      0 ::1:953                 :::*                    LISTEN      3037/named
***tcp6    0      0 :::443                  :::*                    LISTEN      19143/httpd
tcp6       0      0 :::3306                 :::*                    LISTEN      2860/mysqld
tcp6       0      0 :::2222                 :::*                    LISTEN      19694/directadmin
tcp6       0      0 :::111                  :::*                    LISTEN      1/systemd
***tcp6    0      0 :::80                   :::*                    LISTEN      19248/varnishd
***tcp6    0      0 :::8080                 :::*                    LISTEN      19143/httpd
tcp6       0      0 :::53                   :::*                    LISTEN      3037/named
tcp6       0      0 :::21                   :::*                    LISTEN      2226/pure-ftpd
tcp6       0      0 :::22                   :::*                    LISTEN      2201/sshd
udp        0      0 {ip}:53                 0.0.0.0:*                           3037/named
udp        0      0 127.0.0.1:53            0.0.0.0:*                           3037/named
udp        0      0 0.0.0.0:111             0.0.0.0:*                           1/systemd
udp        0      0 127.0.0.1:323           0.0.0.0:*                           1341/chronyd
udp        0      0 0.0.0.0:659             0.0.0.0:*                           1356/rpcbind
udp6       0      0 :::53                   :::*                                3037/named
udp6       0      0 :::111                  :::*                                1/systemd
udp6       0      0 ::1:323                 :::*                                1341/chronyd
udp6       0      0 :::659                  :::*                                1356/rpcbind

Now the problems (with above settings):

https://{domain}.com/ causes NET::ERR_CERT_AUTHORITY_INVALID

https://www.{domain}.com/ causes ERR_TOO_MANY_REDIRECTS

https://{domain}.com/test.php causes NET::ERR_CERT_AUTHORITY_INVALID

https://www.{domain}.com/test.php works fine (tho not served by Varnish)

with server alias on:

https://{domain}.com/ infinite loading

https://www.{domain}.com/ infinite loading

https://{domain}.com/test.php works fine (tho not served by Varnish)

https://www.{domain}.com/test.php works fine (tho not served by Varnish)

I don't think it makes sense to paste every single combination of settings and errors thus I would like to ask you if you can see where the problem might be (other than the use of DA).

Since I think that it is before it gets to varnish.params and varnish.vcl I didn't paste those files. I somewhat suspect .htaccess but you will tell me what other files I should paste.


问:
SQL error Column count doesn't match value count at row 1
Am I missing an error with the following to insert into a table with four columns, message_id (auto-incremented) message_sender, message_reciever, message_body. I have checked similar questions and haven't found the solution.
'''</p>

```<code>        <% String sender_id = request.getParameter("message_sender");
        String reciever_id = request.getParameter("message_reciever");
        String message = request.getParameter("message_body");

        try{
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/fyp", "root", "Kmd116352323!");
        Statement st = con.createStatement();

        st.executeUpdate("INSERT INTO messages(message_sender,message_reciever,message_body) VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')");

        out.println("Your request has been noted."
                + " Please return to your user profile or log out");

        } catch(Exception e){
        out.println(e);
                }
        %>
</code>```

答:
This is incorrect:

```<code>VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')
</code>```

You have a ' wrapping the all the values... Which means sql will think you are only sending 1 value. If they are all text values it should be like this:

```<code>VALUES('"+sender_id+"', '"+reciever_id+"' , '"+message+"')
</code>```

If you know some of the values are of INT type then you do not need the ' for that value:

```<code>VALUES("+sender_id+", "+reciever_id+" , '"+message+"')
</code>```

Text values need to be wrapped with a '

Body:
Am I missing an error with the following to insert into a table with four columns, message_id (auto-incremented) message_sender, message_reciever, message_body. I have checked similar questions and haven't found the solution.
'''

        <% String sender_id = request.getParameter("message_sender");
        String reciever_id = request.getParameter("message_reciever");
        String message = request.getParameter("message_body");

        try{
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/fyp", "root", "Kmd116352323!");
        Statement st = con.createStatement();

        st.executeUpdate("INSERT INTO messages(message_sender,message_reciever,message_body) VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')");

        out.println("Your request has been noted."
                + " Please return to your user profile or log out");

        } catch(Exception e){
        out.println(e);
                }
        %>

Body:
This is incorrect:

VALUES('"+sender_id+", "+reciever_id+" , "+message+" ')

You have a ' wrapping the all the values... Which means sql will think you are only sending 1 value. If they are all text values it should be like this:

VALUES('"+sender_id+"', '"+reciever_id+"' , '"+message+"')

If you know some of the values are of INT type then you do not need the ' for that value:

VALUES("+sender_id+", "+reciever_id+" , '"+message+"')

Text values need to be wrapped with a '


问:
Sum netchanges between shapshots in transactional fact
I have a transactional fact with irregular effective from and effectiveTo dates with cumulative total and net changes over ID and time.

Now I want to sum the net changes between two snapshots, for example 2012-01-01 and 2015-07-01 that should include all the rows including and between the snapshot dates.

I would like to select the relevant rows using the snapshot dates so that I can perform a sum on NC_Total grouped on ID.

What is the most efficient way to to this? Can I create a table valued function for this?

This is how the table looks selected for ID IN (1,2):

This is the resultset I should get back using the snapshot dates:

Select rows on snapshot date

And this is how I would like to finally sum it:

Sum of snapshot dates

答:
I think you just want inequalities in a where clause:

```<code>select t.*
from t
where effectiveTo >= '2012-01-01' and
      startFrom <= '2015-06-01'
</code>```

Then you can use aggregation:

```<code>select id, sum(nc_total) as sum_net_changes
from t
where effectiveTo >= '2012-01-01' and
      startFrom <= '2015-06-01'
</code>```

Body:
I think you just want inequalities in a where clause:

select t.*
from t
where effectiveTo >= '2012-01-01' and
      startFrom <= '2015-06-01'

Then you can use aggregation:

select id, sum(nc_total) as sum_net_changes
from t
where effectiveTo >= '2012-01-01' and
      startFrom <= '2015-06-01'


问:
Kafka Connect : Can any field in avro schema ignore when sink data to database table?
I have an requirement that needs a avro schema for multi purpose. Some fields in avro schema does not need to sink in database table. For example :

My avro schema is :

```<code>{
  "namespace": "com.test.clearing",
  "type": "record",
  "name": "ClearingTest",
  "fields": [
    {
      "name": "ID",
      "type": "int"
    },
    {
      "name": "ITEM",
      "type": "string"
    },
    {
        "name": "STAT",
        "type": "string"
    }
  ]
}
</code>```

and my table DDL is:

```<code>-- auto-generated definition
create table CLEARING_TEST
(
    ID int not null primary key,
    ITEM varchar(200) null
);
</code>```

Can i ignore STAT field in kafka connector for sinking in database?

答:
You can use Kafka Connect's Single Message Transform (SMT) and more precisely replaceField using blacklist in order to drop a field so that it is ignored when inserting messages from Kafka to your target database:

```<code>"transforms": "ReplaceField",
"transforms.ReplaceField.type": "org.apache.kafka.connect.transforms.ReplaceField$Value",
"transforms.ReplaceField.blacklist": "STAT"
</code>```

Now the original message:

```<code>{"ID": 1, "ITEM": "myItem", "STAT": "myStat"}
</code>```

will be transformed to:

```<code>{"ID": 1, "ITEM": "myItem"}
</code>```

Body:
I have an requirement that needs a avro schema for multi purpose. Some fields in avro schema does not need to sink in database table. For example :

My avro schema is :

{
  "namespace": "com.test.clearing",
  "type": "record",
  "name": "ClearingTest",
  "fields": [
    {
      "name": "ID",
      "type": "int"
    },
    {
      "name": "ITEM",
      "type": "string"
    },
    {
        "name": "STAT",
        "type": "string"
    }
  ]
}

and my table DDL is:

-- auto-generated definition
create table CLEARING_TEST
(
    ID int not null primary key,
    ITEM varchar(200) null
);

Can i ignore STAT field in kafka connector for sinking in database?

Body:
You can use Kafka Connect's Single Message Transform (SMT) and more precisely replaceField using blacklist in order to drop a field so that it is ignored when inserting messages from Kafka to your target database:

"transforms": "ReplaceField",
"transforms.ReplaceField.type": "org.apache.kafka.connect.transforms.ReplaceField$Value",
"transforms.ReplaceField.blacklist": "STAT"

Now the original message:

{"ID": 1, "ITEM": "myItem", "STAT": "myStat"}

will be transformed to:

{"ID": 1, "ITEM": "myItem"}


问:
get view id from oncontextitemselected
I've several buttons registered for context menu

how do I know which button was clicked for the menu to appear?

below is the pseudocode that i'll be using. I need to do something related to which button clicked (I have few more buttons to be declared), how do I know that the context menu is activated from which button click.

EDIT: I think i didn't make myself clear, I wanted to know which button was clicked for the menu to appear. Not which menu item is clicked. Anyways, I've a solution which I'll add in pretty soon.

thanks

```<code>private static final int SEND_AS_TEXT = Menu.FIRST;
private static final int SEND_AS_IMAGE = Menu.FIRST + 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sendAllBtn = (Button)findViewById(R.id.sendAllBtn);
        sendAllBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        registerForContextMenu(v);
        openContextMenu(v);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch(item.getItemId()){
        case SEND_AS_TEXT:
            //do sth related to the button clicked
            break;

        }
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        // TODO Auto-generated method stub
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(Menu.NONE, SEND_AS_TEXT, SEND_AS_TEXT, "Send As Text");
        menu.add(Menu.NONE, SEND_AS_IMAGE, SEND_AS_IMAGE, "Send As Image");
    }
</code>```

答:
Ok, thanks alot for the help from the others which clear my doubts on the getItemId since it returns the ID that I assigned to the menu item.
In my case, I wanted to know which button was clicked before the contextmenu was created.

To do this, I simply create a long variable to store the button that was clicked. The ID of the button can be obtained as in the following:

```<code>@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    // TODO Auto-generated method stub
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Send As..");
    menu.add(Menu.NONE, SEND_AS_TEXT, SEND_AS_TEXT, "Send As Text");
    menu.add(Menu.NONE, SEND_AS_IMAGE, SEND_AS_IMAGE, "Send As Image");
    btnId = v.getId(); //this is where I get the id of my clicked button
}
</code>```

and later on I'll only need to refer to this btnId to do whatever I want.

ContentLicense: CC BY-SA 3.0

Title: get view id from oncontextitemselected

Body:
I've several buttons registered for context menu

how do I know which button was clicked for the menu to appear?

below is the pseudocode that i'll be using. I need to do something related to which button clicked (I have few more buttons to be declared), how do I know that the context menu is activated from which button click.

EDIT: I think i didn't make myself clear, I wanted to know which button was clicked for the menu to appear. Not which menu item is clicked. Anyways, I've a solution which I'll add in pretty soon.

thanks

private static final int SEND_AS_TEXT = Menu.FIRST;
private static final int SEND_AS_IMAGE = Menu.FIRST + 1;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        sendAllBtn = (Button)findViewById(R.id.sendAllBtn);
        sendAllBtn.setOnClickListener(this);
    }

    @Override
    public void onClick(View v) {
        // TODO Auto-generated method stub
        registerForContextMenu(v);
        openContextMenu(v);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        // TODO Auto-generated method stub
        AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
        switch(item.getItemId()){
        case SEND_AS_TEXT:
            //do sth related to the button clicked
            break;

        }
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v,
            ContextMenuInfo menuInfo) {
        // TODO Auto-generated method stub
        super.onCreateContextMenu(menu, v, menuInfo);
        menu.add(Menu.NONE, SEND_AS_TEXT, SEND_AS_TEXT, "Send As Text");
        menu.add(Menu.NONE, SEND_AS_IMAGE, SEND_AS_IMAGE, "Send As Image");
    }

Body:
Ok, thanks alot for the help from the others which clear my doubts on the getItemId since it returns the ID that I assigned to the menu item.
In my case, I wanted to know which button was clicked before the contextmenu was created.

To do this, I simply create a long variable to store the button that was clicked. The ID of the button can be obtained as in the following:

@Override
public void onCreateContextMenu(ContextMenu menu, View v,
        ContextMenuInfo menuInfo) {
    // TODO Auto-generated method stub
    super.onCreateContextMenu(menu, v, menuInfo);
    menu.setHeaderTitle("Send As..");
    menu.add(Menu.NONE, SEND_AS_TEXT, SEND_AS_TEXT, "Send As Text");
    menu.add(Menu.NONE, SEND_AS_IMAGE, SEND_AS_IMAGE, "Send As Image");
    btnId = v.getId(); //this is where I get the id of my clicked button
}

and later on I'll only need to refer to this btnId to do whatever I want.


问:
Blob request in different language
Im trying to use a private API and i have a problem im unable to solve. The JavaScript code im trying to recreate is

```<code>XMLHttpRequest.send(blob);
</code>```

Blob has the type: "image/jpeg" and a size.
The blob is created from a html input.
Im relativly new to JavaScript and web development so please excuse if this is unclear.
My question is how to recreate this request in any other language preferably Java, Python or NodeJS. As far as i know is blob just a large binary object but i cant find any information how to create a blob like object in any other language.
I hope this question is kind of clear.

答:
In Node.js You could do the following, There is no blob in node.js, you can Buffer instead of blob.

Please check this out.

let imageData = imageFile.toString('base64')
let data = Buffer.from(imageData, 'base64');

var post_options = {
      host: '<domain>',
      path: '<path>',
      method: 'POST',
      body: data,
      headers: {
          'Content-Type': 'image/jpeg',
          'Content-Length': Buffer.byteLength(data)
      }
  };

  // Set up the request
  var post_req = http.request(post_options, function(res) {
    // handle response
  });```

Title: Blob request in different language

Body:
Im trying to use a private API and i have a problem im unable to solve. The JavaScript code im trying to recreate is

XMLHttpRequest.send(blob);

Blob has the type: "image/jpeg" and a size.
The blob is created from a html input.
Im relativly new to JavaScript and web development so please excuse if this is unclear.
My question is how to recreate this request in any other language preferably Java, Python or NodeJS. As far as i know is blob just a large binary object but i cant find any information how to create a blob like object in any other language.
I hope this question is kind of clear.


问:
How to add a checkbox inside Table for Reportlab in python?
I am trying to generate PDF through python by using reportlab. (beginner level)

Basically, I want to create a table with a checkbox inside.

For example, refer to below code:

```<code>    ...
    data =[
        [Paragraph("Option 1",style=custom_para), "anything"],
        [Paragraph("Option 2",style=custom_para), "anything"]
    ]

    t=Table(data, style=style_table, colWidths=[100, 100])
    Story.append(t)
    ...
</code>```

I already tested that the above code can generate table correctly.

Now, I want something further, which is something like:

```<code>    ...
    data =[
        [Paragraph("Option 1",style=custom_para), checkbox_1],
        [Paragraph("Option 2",style=custom_para), checkbox_2]
    ]

    t=Table(data, style=style_table, colWidths=[100, 100])
    Story.append(t)
    ...
</code>```

How should I implement the checkbox_1, checkbox_2?

What is the most efficient way to achieve this?

答:
I hope this helps. I created checkbox_1 and checkbox_2 as instances of the class:

```<code>class InteractiveCheckBox(Flowable):
    def __init__(self, text='A Box'):
        Flowable.__init__(self)
        self.text = text
        self.boxsize = 12

    def draw(self):
        self.canv.saveState()
        form = self.canv.acroForm
        form.checkbox(checked=False,
                      buttonStyle='check',
                      name=self.text,
                      tooltip=self.text,
                      relative=True,
                      size=self.boxsize)
        self.canv.restoreState()
        return
</code>```

Then you can do something like:

```<code>...
checkbox_1 = InteractiveCheckBox('cb1')
checkbox_2 = InteractiveCheckBox('cb2')
data =[
    [Paragraph("Option 1",style=custom_para), checkbox_1],
    [Paragraph("Option 2",style=custom_para), checkbox_2]
]

t=Table(data, style=style_table, colWidths=100])
Story.append(t)
...
</code>```

Body:
I am trying to generate PDF through python by using reportlab. (beginner level)

Basically, I want to create a table with a checkbox inside.

For example, refer to below code:

    ...
    data =[
        [Paragraph("Option 1",style=custom_para), "anything"],
        [Paragraph("Option 2",style=custom_para), "anything"]
    ]

    t=Table(data, style=style_table, colWidths=[100, 100])
    Story.append(t)
    ...

I already tested that the above code can generate table correctly.

Now, I want something further, which is something like:

    ...
    data =[
        [Paragraph("Option 1",style=custom_para), checkbox_1],
        [Paragraph("Option 2",style=custom_para), checkbox_2]
    ]

    t=Table(data, style=style_table, colWidths=[100, 100])
    Story.append(t)
    ...

How should I implement the checkbox_1, checkbox_2?

What is the most efficient way to achieve this?

Body:
I hope this helps. I created checkbox_1 and checkbox_2 as instances of the class:

class InteractiveCheckBox(Flowable):
    def __init__(self, text='A Box'):
        Flowable.__init__(self)
        self.text = text
        self.boxsize = 12

    def draw(self):
        self.canv.saveState()
        form = self.canv.acroForm
        form.checkbox(checked=False,
                      buttonStyle='check',
                      name=self.text,
                      tooltip=self.text,
                      relative=True,
                      size=self.boxsize)
        self.canv.restoreState()
        return

Then you can do something like:

...
checkbox_1 = InteractiveCheckBox('cb1')
checkbox_2 = InteractiveCheckBox('cb2')
data =[
    [Paragraph("Option 1",style=custom_para), checkbox_1],
    [Paragraph("Option 2",style=custom_para), checkbox_2]
]

t=Table(data, style=style_table, colWidths=100])
Story.append(t)
...


问:
Why Ansible get_url gives error about checksums?
I have a task in my ansible playbook, that downloads a java archive from a github url.
The task is here:

```<code>- name: Download Jar Plugin
  get_url:
    url: https://GitHub-URL/plugins-1.0.5.jar
    dest: /app/plugins/
</code>```

There's no mention of checksum, yet it gives this error:

```<code>fatal: [host]: FAILED! => {"changed": false, "msg": "attempted to take checksum of directory: /app/plugins/plugins-1.0.5.jar"}
</code>```

anyone has any idea about this? Is there any workaround to make it download this java archive?

答:
Try adding checksum argument as below:

```<code>- name: Download Jar Plugin
  get_url:
   url: https://GitHub-URL/plugins-1.0.5.jar
   dest: /app/plugins/
   timeout: 200
   checksum: <yourchecksum>
</code>```

Hope this helps as per your error.

Body:
I have a task in my ansible playbook, that downloads a java archive from a github url.
The task is here:

- name: Download Jar Plugin
  get_url:
    url: https://GitHub-URL/plugins-1.0.5.jar
    dest: /app/plugins/

There's no mention of checksum, yet it gives this error:

fatal: [host]: FAILED! => {"changed": false, "msg": "attempted to take checksum of directory: /app/plugins/plugins-1.0.5.jar"}

anyone has any idea about this? Is there any workaround to make it download this java archive?

Body:
Try adding checksum argument as below:

- name: Download Jar Plugin
  get_url:
   url: https://GitHub-URL/plugins-1.0.5.jar
   dest: /app/plugins/
   timeout: 200
   checksum: <yourchecksum>

Hope this helps as per your error.


问:
Swift how to add compiler warning to function
I wrote a simple extension to a viewController and I would like to put a warning so that other developers don't call this function directly. I am not sure if there is an attribute that can serve this purpose in swift :

My code :

```<code>
internal extension UIViewController {

    // add warning so that it can appear when another developer wants to directly access this function
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}

</code>```

So when another develop tries to do something like :

```<code>let viewController = TestViewController()
viewController.removeFromParent()
</code>```

They should get warning that you can't use this function directly

答:
Add warning->

Also you can use #error("your message")

```<code>internal extension UIViewController {

    #warning("Your warning message")
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}
</code>```

Add warning when function called->

```<code>internal extension UIViewController {

    //@available(*, unavailable)

    //@available(*, deprecated, message: "your warning message")

    //@available(*, deprecated, renamed: "new name")

    //@available(swift, introduced: 5)
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}
</code>```

@available options:

unavailable

introduced

deprecated

obsoleted

message

renamed

If you need more examples please visit hackingwithswift

Body:
I wrote a simple extension to a viewController and I would like to put a warning so that other developers don't call this function directly. I am not sure if there is an attribute that can serve this purpose in swift :

My code :

internal extension UIViewController {

    // add warning so that it can appear when another developer wants to directly access this function
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}

So when another develop tries to do something like :

let viewController = TestViewController()
viewController.removeFromParent()

They should get warning that you can't use this function directly

Body:
Add warning->

Also you can use #error("your message")

internal extension UIViewController {

    #warning("Your warning message")
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}

Add warning when function called->

internal extension UIViewController {

    //@available(*, unavailable)

    //@available(*, deprecated, message: "your warning message")

    //@available(*, deprecated, renamed: "new name")

    //@available(swift, introduced: 5)
    func removeFromParent() {

        self.willMove(toParent: nil)
        self.view.removeFromSuperview()
        self.removeFromParent()
    }
}

@available options:

unavailable

introduced

deprecated

obsoleted

message

renamed

If you need more examples please visit hackingwithswift


问:
How to access to accelerometer sensor of android phone using flutter app?
I need to display a push notification when my android phone faced a  motion using flutter android application . How can I do that ?

答:
pubspec.yaml

dependencies:
  sensors: ^0.4.1+7 (dont forget to install)

file.dart

```<code>import 'package:sensors/sensors.dart';

accelerometerEvents.listen((AccelerometerEvent event) {
  print(event);
});
// [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)]
</code>```

Velocity of the device, including the effects of gravity

```<code>userAccelerometerEvents.listen((UserAccelerometerEvent event) {
  print(event);
});
// [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)]
</code>```

Also describes the velocity of the device, but doesnt include gravity.

```<code>gyroscopeEvents.listen((GyroscopeEvent event) {
  print(event);
});
// [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)]
</code>```

rotation of device

Hope this helps

Body:
pubspec.yaml

dependencies:
  sensors: ^0.4.1+7 (dont forget to install)

file.dart

import 'package:sensors/sensors.dart';

accelerometerEvents.listen((AccelerometerEvent event) {
  print(event);
});
// [AccelerometerEvent (x: 0.0, y: 9.8, z: 0.0)]

Velocity of the device, including the effects of gravity

userAccelerometerEvents.listen((UserAccelerometerEvent event) {
  print(event);
});
// [UserAccelerometerEvent (x: 0.0, y: 0.0, z: 0.0)]

Also describes the velocity of the device, but doesnt include gravity.

gyroscopeEvents.listen((GyroscopeEvent event) {
  print(event);
});
// [GyroscopeEvent (x: 0.0, y: 0.0, z: 0.0)]

rotation of device

Hope this helps


问:
Saving multiple lists as a csv file in python
I am trying to read multiple xml files and extract the data from these files. I am trying to extract two sets of data and save them into two separate csv files.

From the extractData function, I get a list of data from a single file. In the createCSV function, I extract only the data which I require.

I want to save all the extracted data from all the files I read into one csv file. Currently, I am only able to save the last file.

```<code>import json
import os
import pandas as pd
import numpy as np
import bs4
import glob
import csv

def extractData(path):
    for filename in glob.glob(os.path.join(path, '*.xml')):
        genre = bs4.BeautifulSoup(open(filename, 'r', encoding="utf8"), features="lxml")
        #print(genre)
        if genre.find_all("name") == []:
            print('Not Available')
        else:
            tags = genre.find_all("name")
            genre_list = []
            for name in tags:
                genres = name.text.strip()
                genre_list.append(genres)
            #print(genre_list)
    return genre_list

def createCSV(list_genre):
    new_artist_list = []
    new_genre_list = []
    complete_list = pd.DataFrame(list_genre)
    new_col = len(complete_list)
    #print(complete_list)
    #print(new_col)
    if new_col == 2:
        #for complete_list in complete_lists:
        column_names_1 = ["Song", "Artist"]
        final_list_1 = complete_list.T
        final_list_1.columns = column_names_1
        #print(final_list_1)
        new_artist_list.append(final_list_1)
        #print(new_artist_list)
    elif new_col > 2:
        #for complete_list in complete_lists:
        column_names_2 = ["Song", "Artist", "Genre"]
        #print(complete_list)
        final_list_2 = complete_list.T
        final_list_3 = np.array(final_list_2)
        #print(final_list_3)
        song_list = final_list_3[:, 0]
        artist_list = final_list_3[:, 1]
        final_list_2['Genre'] = final_list_2[final_list_2.columns[2:]].apply(lambda x: ','.join(x.dropna().astype(str)), axis=1)
        #print(final_list_2['Genre'])
        combined = np.concatenate((song_list, artist_list))
        combined_list = np.concatenate((combined, final_list_2['Genre']))
        #print(combined_list)
        complete_list_final = pd.DataFrame(combined_list)
        #print(complete_list_final)
        complete_list_final_1 = complete_list_final.T
        complete_list_final_1.columns = column_names_2
        new_genre_list.append(complete_list_final_1)
        #print(new_genre_list)
    print(new_artist_list)
    print(new_genre_list)
    return new_artist_list, new_genre_list

def writeCSV(partial_list, complete_list):
    partial_lists = partial_list
    complete_lists = complete_list
    artist_init = []
    complete_init = []
    for i, j in zip(partial_lists, complete_lists):
        with open('data_only_artist_name.csv', 'w', encoding="utf8") as data_partial:
            artist_csv = csv.writer(data_partial)
            artist_csv.writerow(i)
            artist_init.append(artist_csv)

        with open('data_complete.csv', 'w', encoding="utf8") as data_complete:
            complete_csv = csv.writer(data_complete)
            complete_csv.writerow(j)
            complete_init.append(complete_csv)
            #print(new_genre_list)
    a = artist_init
    b = complete_init
    return a, b

path = 'XML Data'
data = extractData(path)
print(data)
partial, complete = createCSV(data)
list_partial, list_complete = writeCSV(partial, complete)
</code>```

答:
In write_csv you open the files in w mode, so you truncate them to 0 size on each pass and at the end you only have the values from the last pass.

Use a mode instead (with open(..., 'a', encoding="utf8") as ...) and you will add new data after previous one.

Body:
I am trying to read multiple xml files and extract the data from these files. I am trying to extract two sets of data and save them into two separate csv files.

From the extractData function, I get a list of data from a single file. In the createCSV function, I extract only the data which I require.

I want to save all the extracted data from all the files I read into one csv file. Currently, I am only able to save the last file.

import json
import os
import pandas as pd
import numpy as np
import bs4
import glob
import csv

def extractData(path):
    for filename in glob.glob(os.path.join(path, '*.xml')):
        genre = bs4.BeautifulSoup(open(filename, 'r', encoding="utf8"), features="lxml")
        #print(genre)
        if genre.find_all("name") == []:
            print('Not Available')
        else:
            tags = genre.find_all("name")
            genre_list = []
            for name in tags:
                genres = name.text.strip()
                genre_list.append(genres)
            #print(genre_list)
    return genre_list

def createCSV(list_genre):
    new_artist_list = []
    new_genre_list = []
    complete_list = pd.DataFrame(list_genre)
    new_col = len(complete_list)
    #print(complete_list)
    #print(new_col)
    if new_col == 2:
        #for complete_list in complete_lists:
        column_names_1 = ["Song", "Artist"]
        final_list_1 = complete_list.T
        final_list_1.columns = column_names_1
        #print(final_list_1)
        new_artist_list.append(final_list_1)
        #print(new_artist_list)
    elif new_col > 2:
        #for complete_list in complete_lists:
        column_names_2 = ["Song", "Artist", "Genre"]
        #print(complete_list)
        final_list_2 = complete_list.T
        final_list_3 = np.array(final_list_2)
        #print(final_list_3)
        song_list = final_list_3[:, 0]
        artist_list = final_list_3[:, 1]
        final_list_2['Genre'] = final_list_2[final_list_2.columns[2:]].apply(lambda x: ','.join(x.dropna().astype(str)), axis=1)
        #print(final_list_2['Genre'])
        combined = np.concatenate((song_list, artist_list))
        combined_list = np.concatenate((combined, final_list_2['Genre']))
        #print(combined_list)
        complete_list_final = pd.DataFrame(combined_list)
        #print(complete_list_final)
        complete_list_final_1 = complete_list_final.T
        complete_list_final_1.columns = column_names_2
        new_genre_list.append(complete_list_final_1)
        #print(new_genre_list)
    print(new_artist_list)
    print(new_genre_list)
    return new_artist_list, new_genre_list

def writeCSV(partial_list, complete_list):
    partial_lists = partial_list
    complete_lists = complete_list
    artist_init = []
    complete_init = []
    for i, j in zip(partial_lists, complete_lists):
        with open('data_only_artist_name.csv', 'w', encoding="utf8") as data_partial:
            artist_csv = csv.writer(data_partial)
            artist_csv.writerow(i)
            artist_init.append(artist_csv)

        with open('data_complete.csv', 'w', encoding="utf8") as data_complete:
            complete_csv = csv.writer(data_complete)
            complete_csv.writerow(j)
            complete_init.append(complete_csv)
            #print(new_genre_list)
    a = artist_init
    b = complete_init
    return a, b

path = 'XML Data'
data = extractData(path)
print(data)
partial, complete = createCSV(data)
list_partial, list_complete = writeCSV(partial, complete)


问:
Running node.exe from Django on Heroku - [Errno 2] No such file or directory
I'm deploying a Django project Heroku. I need to run node.exe, so I copied node.exe to my folder and deploy all them to Heroku.

Here is the code use with node in Django:

```<code>def extract_eval_unpacked(text):
    with io.open('temp.js','w',encoding='utf-8') as f:
        f.write(text)
    cmd = 'node.exe temp.js'
    process = subprocess.check_output(cmd,shell=False)
    if process:
        return process.decode()
    return None
</code>```

This works locally, but when run on Heroku I get

```<code>[Errno 2] No such file or directory: 'node.exe temp.js': 'node.exe temp.js'
</code>```

I checked on Heroku and I see node.exe:

```<code>$ heroku run ls
Running ls on ⬢ extractmedia... up, run.4541 (Free)
1         client_id.txt   manage.py  Procfile.windows  runtime.txt  test1.py
1.py      gettingstarted  node.exe   README.md         staticfiles
app.json  hello           Procfile   requirements.txt  temp.js
</code>```

Why isn't this working, and how can I fix it?

答:
I need to run node.exe, so I copied node.exe to my folder and deploy all them to Heroku

Don't do this.

Heroku doesn't run Windows, so it won't be able to execute a Windows binary like node.exe. There's a much better way to add Node.js to your application: use multiple buildpacks.

Set your main buildpack:

```<code>heroku buildpacks:set heroku/python
</code>```

Add a second buildpack for Node.js:

```<code>heroku buildpacks:add --index 1 heroku/nodejs
</code>```

Check your buildpacks and make sure that Python comes last:

```<code>heroku buildpacks
</code>```

Add a package.json file to the root of your repository, e.g. by running npm init or yarn init.

If you depend on any specific Node.js libraries, include them as dependencies, e.g. via yarn add or npm install --save. Commit this file.

Update your Python to call node instead of node.exe. Commit that change.

Deploy.

You should see Node.js and any JavaScript dependencies get installed, followed by Python and all of your Python dependencies. node should be available at runtime.

Body:
I'm deploying a Django project Heroku. I need to run node.exe, so I copied node.exe to my folder and deploy all them to Heroku.

Here is the code use with node in Django:

def extract_eval_unpacked(text):
    with io.open('temp.js','w',encoding='utf-8') as f:
        f.write(text)
    cmd = 'node.exe temp.js'
    process = subprocess.check_output(cmd,shell=False)
    if process:
        return process.decode()
    return None

This works locally, but when run on Heroku I get

[Errno 2] No such file or directory: 'node.exe temp.js': 'node.exe temp.js'

I checked on Heroku and I see node.exe:

$ heroku run ls
Running ls on ⬢ extractmedia... up, run.4541 (Free)
1         client_id.txt   manage.py  Procfile.windows  runtime.txt  test1.py
1.py      gettingstarted  node.exe   README.md         staticfiles
app.json  hello           Procfile   requirements.txt  temp.js

Why isn't this working, and how can I fix it?

Body:
I need to run node.exe, so I copied node.exe to my folder and deploy all them to Heroku

Don't do this.

Heroku doesn't run Windows, so it won't be able to execute a Windows binary like node.exe. There's a much better way to add Node.js to your application: use multiple buildpacks.

Set your main buildpack:

heroku buildpacks:set heroku/python

Add a second buildpack for Node.js:

heroku buildpacks:add --index 1 heroku/nodejs

Check your buildpacks and make sure that Python comes last:

heroku buildpacks

Add a package.json file to the root of your repository, e.g. by running npm init or yarn init.

If you depend on any specific Node.js libraries, include them as dependencies, e.g. via yarn add or npm install --save. Commit this file.

Update your Python to call node instead of node.exe. Commit that change.

Deploy.

You should see Node.js and any JavaScript dependencies get installed, followed by Python and all of your Python dependencies. node should be available at runtime.