问:
Best way to Bulk-remove records? Can I chain multiple remove bulk operations in MongoDB?
I have a collection where some documents happen to have different types for the same property. I want to remove the documents that are incorrect based on that criteria. So I think I can do this:

var db = db.getSiblingDB('db'),
   coll = db.getCollection("coll"),
    bulk = coll.initializeUnorderedBulkOp();
    /* some stuff in between here and there */
bulk.find(
    {
        "doc.prop1": { $exists: true }
    }
).remove();

bulk.find(
    {
        "doc.prop2":{
            $exists: true,
            $isArray: true,
            $elemMatch: {
                "elem": { $type: "object" }
            }
        }
).remove();

bulk.execute(); ```

What is best way do remove records according to multiple queries/filters in a single bulk operation?

答:
I had a similar issue where _id values were either String or ObjectId (legacy db...) Using the script below, all were converted to ObjectId. Load it using mongo load.

```<code>// find the length of collection (collection name is "documents")

var total = db.documents.find().length();
print("found " + total + " documents");

// Now find all the items that need to be updated
var documentCursor = db.documents.find().limit(total);

var toBeDeleted = [];

documentCursor.forEach(function(doc) {
    print("Starting with item # " + total);
    var oldId = doc._id; // store old id
    print(" --> oldId : ", oldId);

    try {
        doc._id = new ObjectId();
        db.documents.insert(doc);
        print("new id: ", doc._id);
        toBeDeleted.push(oldId);
        total = total - 1;
    } catch (e) {
        print("failed to insert: ", e);
    }
});

// Afterwards delete the old items
try {
    db.documents.deleteMany({ _id: { $in: toBeDeleted } });
} catch (e) {
    print("Failed to delete: ", e);
}

</code>```

The deletion was necessary because _id can't be updated. For other properties I would do something similar but then use updateMany

Recent backup is a no brainer. What I really liked was that I could easily reload that specific collection and start over.
  I use mlab and their docs after login quickly helped me to restore the collection.

Body:
I have a collection where some documents happen to have different types for the same property. I want to remove the documents that are incorrect based on that criteria. So I think I can do this:

var db = db.getSiblingDB('db'),
   coll = db.getCollection("coll"),
    bulk = coll.initializeUnorderedBulkOp();
    /* some stuff in between here and there */
bulk.find(
    {
        "doc.prop1": { $exists: true }
    }
).remove();

bulk.find(
    {
        "doc.prop2":{
            $exists: true,
            $isArray: true,
            $elemMatch: {
                "elem": { $type: "object" }
            }
        }
).remove();

bulk.execute();

What is best way do remove records according to multiple queries/filters in a single bulk operation?

Body:
I had a similar issue where _id values were either String or ObjectId (legacy db...) Using the script below, all were converted to ObjectId. Load it using mongo load.

// find the length of collection (collection name is "documents")

var total = db.documents.find().length();
print("found " + total + " documents");

// Now find all the items that need to be updated
var documentCursor = db.documents.find().limit(total);

var toBeDeleted = [];

documentCursor.forEach(function(doc) {
    print("Starting with item # " + total);
    var oldId = doc._id; // store old id
    print(" --> oldId : ", oldId);

    try {
        doc._id = new ObjectId();
        db.documents.insert(doc);
        print("new id: ", doc._id);
        toBeDeleted.push(oldId);
        total = total - 1;
    } catch (e) {
        print("failed to insert: ", e);
    }
});

// Afterwards delete the old items
try {
    db.documents.deleteMany({ _id: { $in: toBeDeleted } });
} catch (e) {
    print("Failed to delete: ", e);
}

The deletion was necessary because _id can't be updated. For other properties I would do something similar but then use updateMany

Recent backup is a no brainer. What I really liked was that I could easily reload that specific collection and start over.
  I use mlab and their docs after login quickly helped me to restore the collection.


来源: stackexchange

问:
How to resolve possible scheduling error with async ReactiveCommand?
I'm relatively new to ReactiveUI and I'm trying to asynchronously execute a database query from a ReactiveCommand. From what I can tell, the problem isn't with executing the async query, but when I try to load the results into a ReactiveList in my view model. I believe that this is a scheduling issue but I'm not familiar enough with RxUI to come up with the correct approach.

I've tried subscribing to the command in the view model using ObserveOn with both RxApp.TaskPoolScheduler and RxApp.MainThreadScheduler but neither seems to help.

My view model:

```<code>   public class UsersViewModel : ReactiveObject, IRoutableViewModel
   {
      ReactiveList<LisUser> _users;
      IUserManagementService UsersService { get; }

      public IScreen HostScreen { get; }

      public ReactiveCommand<Unit, IEnumerable<LisUser>> LoadUsers { get; }

      public String UrlPathSegment => "users";

      public ReactiveList<LisUser> Users
      {
         get => _users;
         set => this.RaiseAndSetIfChanged(ref _users, value);
      }

      public UsersSubPageViewModel(
         IScreen screen,
         IUserManagementService usersService)
      {
         HostScreen = screen ?? throw new ArgumentNullException(nameof(screen));
         UsersService =
            usersService ?? throw new ArgumentNullException(nameof(usersService));

         Users = new ReactiveList<LisUser>();
         LoadUsers = ReactiveCommand.CreateFromTask(async () =>
         {
            return await UsersService.GetUsersAsync().ConfigureAwait(false);
         });
         LoadUsers
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(list =>
            {
               Users.Clear();
               foreach (var u in list)
               {
                  Users.Add(u);
               }
            });
      }
   }
</code>```

My view:

```<code>   public partial class UsersView : ReactiveUserControl<UsersViewModel>
   {
      public UsersPageView()
      {
         InitializeComponent();

         this.WhenActivated(disposables =>
         {
            this.WhenAnyValue(x => x.ViewModel.LoadUsers)
               .SelectMany(x => x.Execute())
               .Subscribe()
               .DisposeWith(disposables);
         });
      }
   }
</code>```

What I want to occur is when the UsersView is activated, the GetUsers method of the UsersService executes asynchronously and loads the returned list of users into the Users ReactiveList. Instead, I see a new tab in VS with a title of "Source Not Found" and a message saying that "RxApp.cs not found". The actual exception is a System.Exception with a message stating "Cannot obtain value of the local variable or argument because it is not available at this instruction pointer, possibly because it has been optimized away."

So, my first question is "is this actually a scheduling issue?" And the second question is "how do I resolve it?"

答:
It looks like the issue wasn't scheduling, but async related.

IUserManagementService has a reference to an IUserRepository, which itself has an GetUsersAsync method to actually query the database. The actual implementation of IUserManagementService was missing ConfigureAwait on the call to IUserRepository.GetUsersAsync. This wasn't an issue in the unit tests, but definitely a problem once an UI was involved.

ContentLicense: CC BY-SA 4.0

Body:
I'm relatively new to ReactiveUI and I'm trying to asynchronously execute a database query from a ReactiveCommand. From what I can tell, the problem isn't with executing the async query, but when I try to load the results into a ReactiveList in my view model. I believe that this is a scheduling issue but I'm not familiar enough with RxUI to come up with the correct approach.

I've tried subscribing to the command in the view model using ObserveOn with both RxApp.TaskPoolScheduler and RxApp.MainThreadScheduler but neither seems to help.

My view model:

   public class UsersViewModel : ReactiveObject, IRoutableViewModel
   {
      ReactiveList<LisUser> _users;
      IUserManagementService UsersService { get; }

      public IScreen HostScreen { get; }

      public ReactiveCommand<Unit, IEnumerable<LisUser>> LoadUsers { get; }

      public String UrlPathSegment => "users";

      public ReactiveList<LisUser> Users
      {
         get => _users;
         set => this.RaiseAndSetIfChanged(ref _users, value);
      }

      public UsersSubPageViewModel(
         IScreen screen,
         IUserManagementService usersService)
      {
         HostScreen = screen ?? throw new ArgumentNullException(nameof(screen));
         UsersService =
            usersService ?? throw new ArgumentNullException(nameof(usersService));

         Users = new ReactiveList<LisUser>();
         LoadUsers = ReactiveCommand.CreateFromTask(async () =>
         {
            return await UsersService.GetUsersAsync().ConfigureAwait(false);
         });
         LoadUsers
            .ObserveOn(RxApp.MainThreadScheduler)
            .Subscribe(list =>
            {
               Users.Clear();
               foreach (var u in list)
               {
                  Users.Add(u);
               }
            });
      }
   }

My view:

   public partial class UsersView : ReactiveUserControl<UsersViewModel>
   {
      public UsersPageView()
      {
         InitializeComponent();

         this.WhenActivated(disposables =>
         {
            this.WhenAnyValue(x => x.ViewModel.LoadUsers)
               .SelectMany(x => x.Execute())
               .Subscribe()
               .DisposeWith(disposables);
         });
      }
   }

What I want to occur is when the UsersView is activated, the GetUsers method of the UsersService executes asynchronously and loads the returned list of users into the Users ReactiveList. Instead, I see a new tab in VS with a title of "Source Not Found" and a message saying that "RxApp.cs not found". The actual exception is a System.Exception with a message stating "Cannot obtain value of the local variable or argument because it is not available at this instruction pointer, possibly because it has been optimized away."

So, my first question is "is this actually a scheduling issue?" And the second question is "how do I resolve it?"


问:
What are the Pitfalls of using a shared static WCF Proxy Client?
I am considering using a Shared (read static) WCF proxy client for a high throughput application.  I believe there is a performance gain in doing this, but I have not benchmarked this as yet.

Are there some serious pitfalls to this idea?

From my research I can see that there is the issue of handling the fault state, it is not clear what the flow on affect of this state would be to other pending requests.

Does anyone have any experience recovering a WCF proxy from it's faulted state?

thanks in advance!

答:
Once the channel is in a faulted state it will stay that way. So yes, I think a static client would be problematic. I started off that way as well but ended up creating and opening a new channel for each call instead. There doesn't seem to be much of a performance trade-off.

For reference I'm doing about 30-60 requests of about 5K-30K per request per second on a quad core machine from another quad core machine. WCF has been holding up quite well so far.

OwnerDisplayName: Harry

ContentLicense: CC BY-SA 2.5

OwnerDisplayName: fung


问:
Illegal characters in path when calling the index view from my controller
I am receiving an ArgumentException when invoking the index action of one of my controllers and I am not sure why. The error message is the following:

Server Error in '/' Application.

Illegal characters in path.

```<code>[ArgumentException: Illegal characters in path.]
 System.IO.Path.CheckInvalidPathChars(String path) +126
 System.IO.Path.Combine(String path1, String path2) +38
</code>```

I am not sure why this is happening. here is the code from the controller:

```<code>    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToString();
        return View(glaccounts);
    }
</code>```

答:
I found it finally. It is a really embarassing typo by me. I mistyped the code:

```<code>    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToString();
        return View(glaccounts);
    }
</code>```

instead of:

```<code>    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToList();
        return View(glaccounts);
    }
</code>```

Then the framework wanted to load a view file, like this:

```<code>"~/Views/GLAccount/SELECT \r\n[Extent1].[Id] AS [Id], \r\n[Extent1].[OrgDefinitionId] AS [OrgDefinitionId], \r\n[Extent1].[GLAccountId] AS
[GLAccountId], \r\n[Extent1].[Name] AS [Name], \r\n[Extent1].[StartDate] AS [StartDate],
\r\n[Extent1].[EndDate] AS [EndDate]\r\nFROM [GLAccounts] AS [Extent1].aspx"
</code>```

Hopefully, I will save couple of hours of debugging for someone else by posting this :(

ContentLicense: CC BY-SA 3.0

Body:
I am receiving an ArgumentException when invoking the index action of one of my controllers and I am not sure why. The error message is the following:

Server Error in '/' Application.

Illegal characters in path.

[ArgumentException: Illegal characters in path.]
 System.IO.Path.CheckInvalidPathChars(String path) +126
 System.IO.Path.Combine(String path1, String path2) +38

I am not sure why this is happening. here is the code from the controller:

    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToString();
        return View(glaccounts);
    }

Body:
I found it finally. It is a really embarassing typo by me. I mistyped the code:

    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToString();
        return View(glaccounts);
    }

instead of:

    public ActionResult Index()
    {
        var glaccounts = db.GLAccounts.ToList();
        return View(glaccounts);
    }

Then the framework wanted to load a view file, like this:

"~/Views/GLAccount/SELECT \r\n[Extent1].[Id] AS [Id], \r\n[Extent1].[OrgDefinitionId] AS [OrgDefinitionId], \r\n[Extent1].[GLAccountId] AS
[GLAccountId], \r\n[Extent1].[Name] AS [Name], \r\n[Extent1].[StartDate] AS [StartDate],
\r\n[Extent1].[EndDate] AS [EndDate]\r\nFROM [GLAccounts] AS [Extent1].aspx"

Hopefully, I will save couple of hours of debugging for someone else by posting this :(


问:
Iterating over keys of nested dictionary and adding tabs
I have a nested dictionary like this {"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}},Now i need to recursively iterate over the nested dictionary and create a list of keys of nested dictionary with tabs prepend to it. </p>

```<code>new_d={"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}}
other_list=[]
child=False
tabb='\t'
def put_tabs(d):
  global tabb,child
  for k, v in d.iteritems():
      if v:
          if child:
              other_list.append("{0}{1}".format(tabb,k))
              tabb+='\t'
          else:
              other_list.append("{0}".format(k))
          child=True
          put_tabs(v)
      else:
          if child:
              other_list.append("{0}{1}".format(tabb,k))

          else:
              other_list.append("{0}:".format(k))
          child=False
put_tabs(new_d)
print other_list

# Expected output ['step2', '\tstep7', '\tstep3', '\t\tstep4', 'step1:']
# current ouput ['step2', '\tstep7', 'step3', '\t\step4', 'step1:']
</code>```

答:
```<code>new_d={"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}}

def fn(d, counter):
    for k, v in d.items():
        yield '\t' * counter + k
        if isinstance(v, dict):
            yield from fn(v, counter + 1)

out = []
for p in fn(new_d, 0):
    out += [p]

print(out)
</code>```

Prints:

```<code>['step1', 'step2', '\tstep3', '\t\tstep4', '\tstep7']
</code>```

Body:
I have a nested dictionary like this {"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}},Now i need to recursively iterate over the nested dictionary and create a list of keys of nested dictionary with tabs prepend to it.

new_d={"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}}
other_list=[]
child=False
tabb='\t'
def put_tabs(d):
  global tabb,child
  for k, v in d.iteritems():
      if v:
          if child:
              other_list.append("{0}{1}".format(tabb,k))
              tabb+='\t'
          else:
              other_list.append("{0}".format(k))
          child=True
          put_tabs(v)
      else:
          if child:
              other_list.append("{0}{1}".format(tabb,k))

          else:
              other_list.append("{0}:".format(k))
          child=False
put_tabs(new_d)
print other_list

# Expected output ['step2', '\tstep7', '\tstep3', '\t\tstep4', 'step1:']
# current ouput ['step2', '\tstep7', 'step3', '\t\step4', 'step1:']

Body:
new_d={"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}}

def fn(d, counter):
    for k, v in d.items():
        yield '\t' * counter + k
        if isinstance(v, dict):
            yield from fn(v, counter + 1)

out = []
for p in fn(new_d, 0):
    out += [p]

print(out)

Prints:

['step1', 'step2', '\tstep3', '\t\tstep4', '\tstep7']


问:
How to Install old version go-vim plugin
I am a new golang developer. My company uses go 1.10.2, and I hit following error during installing vim-go

```<code>Error installing golang.org/x/tools/cmd/gopls: # golang.org/x/tools/internal/lsp/source^@../../../golang.org/x/tools/internal/lsp/source/symbols.go:232:18: ti.EmbeddedType undefined (t
ype *types.Interface has no field or method EmbeddedType
</code>```

It turns out due to the old go version. https://github.com/fatih/vim-go/issues/2246, https://github.com/golang/go/issues/31864. Since upgrade go version is not an option, the only choice I can think of is to install an old version vim-go that supports go 1.10.2. But I am not sure how to do so.
This is how I install vim-go now:

```<code>git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go
</code>```

then open up vim and run :GoInstallBinaries (where above error show up)

Any suggestions would be great. Since I am neither a vim nor a go person before, more details would be appreciate!

答:
You should try goenv it support multiple version of golang.

Here is the installation guide

https://github.com/syndbg/goenv/blob/master/INSTALL.md

And after installation you can choose and install any version from the list.

Just by typing..

```<code>goenv install 1.10.2
</code>```

Body:
I am a new golang developer. My company uses go 1.10.2, and I hit following error during installing vim-go

Error installing golang.org/x/tools/cmd/gopls: # golang.org/x/tools/internal/lsp/source^@../../../golang.org/x/tools/internal/lsp/source/symbols.go:232:18: ti.EmbeddedType undefined (t
ype *types.Interface has no field or method EmbeddedType

It turns out due to the old go version. https://github.com/fatih/vim-go/issues/2246, https://github.com/golang/go/issues/31864. Since upgrade go version is not an option, the only choice I can think of is to install an old version vim-go that supports go 1.10.2. But I am not sure how to do so.
This is how I install vim-go now:

git clone https://github.com/fatih/vim-go.git ~/.vim/pack/plugins/start/vim-go

then open up vim and run :GoInstallBinaries (where above error show up)

Any suggestions would be great. Since I am neither a vim nor a go person before, more details would be appreciate!

Body:
You should try goenv it support multiple version of golang.

Here is the installation guide

https://github.com/syndbg/goenv/blob/master/INSTALL.md

And after installation you can choose and install any version from the list.

Just by typing..

goenv install 1.10.2


问:
How can I use AWS CodePipeline to update a container service on ECS
I have a cluster on ECS with a container service. I've setup CodePipeline to build a new container on an update and push this to ECR. How can I trigger an update to my cluster to use the newly updated container?</p>

答:
If you're ok with updating containers to new :latest image, stopping ECS cluster's tasks before deploy works just fine.

In buildspec.yml of AWS CodeBuild stage add

aws ecs list-tasks --cluster "ECS_CLUSTER_NAME" --output text | awk '{print $2}' | while read line ; do aws ecs stop-task --task "$line" --cluster "ECS_CLUSTER_NAME" ; done
```

with the name of your ECS Cluster instead of ECS_CLUSTER_NAME, to post_build commands section just after your docker push... commands.

Containers will be stopped. And ECS will fulfill desired tasks amount with your newly created docker image.

P.S. Don't forget to check IAM so your CodeBuild user role has permissions to perform ecs:* commands.

Body:
If you're ok with updating containers to new :latest image, stopping ECS cluster's tasks before deploy works just fine.

In buildspec.yml of AWS CodeBuild stage add

aws ecs list-tasks --cluster "ECS_CLUSTER_NAME" --output text | awk '{print $2}' | while read line ; do aws ecs stop-task --task "$line" --cluster "ECS_CLUSTER_NAME" ; done

with the name of your ECS Cluster instead of ECS_CLUSTER_NAME, to post_build commands section just after your docker push... commands.

Containers will be stopped. And ECS will fulfill desired tasks amount with your newly created docker image.

P.S. Don't forget to check IAM so your CodeBuild user role has permissions to perform ecs:* commands.


问:
How to Comma separate multiple rows obtained from a SQL Query
```<code>Select s.FirstName, glTitle.LookupItem Title
    from ClientStaff cs
    left outer join Staff s on s.Id = cs.StaffId
    left outer join StaffTitle st on st.StaffId = s.Id
    left outer join GeneralLookup glTitle on glTitle.Id = st.glTitleId
</code>```

It returns these rows:

As you can see, the first column has all same rows because one employee can have multiple titles.

How can I merge all of the titles for each employee into a comma separated value so that there is only one row per employee?

答:
You can use this query.  I have generic template for queries like these that follows this pattern.  You might have to debug this because I don't have your table structure. It coalesces the titles into a list</p>

```<code>DECLARE @List varchar(2000), @otherList varchar(2000),@FirstName varchar(2000),@id varchar(2000)
declare @temp table(
    firstName varchar(128),
    title varchar(4000)
)

DECLARE TitleList CURSOR FAST_FORWARD  FOR
select s.FirstName,  s.Id
from ClientStaff cs
left outer join Staff s on s.Id = cs.StaffId
OPEN TitleList
FETCH NEXT FROM TitleList INTO @FirstName,@id
WHILE @@FETCH_STATUS = 0
BEGIN
    select @List = COALESCE(@List + ',', '') + Cast(glTitle.LookupItem As varchar(400))
    from StaffTitle st
    left outer join GeneralLookup glTitle on glTitle.Id = st.glTitleId
    where st.StaffId = id

    insert into @temp
    select @FirstName,@List
    set @List = null;
FETCH NEXT FROM TitleList INTO @FirstName,@id
END
CLOSE TitleList
DEALLOCATE TitleList

select * from @temp
</code>```

Body:
Select s.FirstName, glTitle.LookupItem Title
    from ClientStaff cs
    left outer join Staff s on s.Id = cs.StaffId
    left outer join StaffTitle st on st.StaffId = s.Id
    left outer join GeneralLookup glTitle on glTitle.Id = st.glTitleId

It returns these rows:

As you can see, the first column has all same rows because one employee can have multiple titles.

How can I merge all of the titles for each employee into a comma separated value so that there is only one row per employee?

Body:
You can use this query.  I have generic template for queries like these that follows this pattern.  You might have to debug this because I don't have your table structure. It coalesces the titles into a list

DECLARE @List varchar(2000), @otherList varchar(2000),@FirstName varchar(2000),@id varchar(2000)
declare @temp table(
    firstName varchar(128),
    title varchar(4000)
)

DECLARE TitleList CURSOR FAST_FORWARD  FOR
select s.FirstName,  s.Id
from ClientStaff cs
left outer join Staff s on s.Id = cs.StaffId
OPEN TitleList
FETCH NEXT FROM TitleList INTO @FirstName,@id
WHILE @@FETCH_STATUS = 0
BEGIN
    select @List = COALESCE(@List + ',', '') + Cast(glTitle.LookupItem As varchar(400))
    from StaffTitle st
    left outer join GeneralLookup glTitle on glTitle.Id = st.glTitleId
    where st.StaffId = id

    insert into @temp
    select @FirstName,@List
    set @List = null;
FETCH NEXT FROM TitleList INTO @FirstName,@id
END
CLOSE TitleList
DEALLOCATE TitleList

select * from @temp


问:
Remove specific values contained in DataFrame
I am trying to check if a specific value is contained anywhere in a certain column of my dataframe. I am using the following code, where it should clear data containing "0.0". However, it seemed like it is clearing data that does not contain "0.0" as well.

```<code>mydataset = mydataset[mydataset['Latitude'].astype(str).str.contains('0.0') == False]
</code>```

Example of the data as follows. Highlighted in red are data being removed, upon applying the above code.

答:
If you are using a pandas dataframe you can conditionally drop rows from your dataframe in the following manner:

```<code>mydataset = mydataset[str(mydataset.Latitude) != '0.0']
</code>```

If you are trying to remove all 0 values and not just 0.0 then don't convert to string and it should drop any 0 value.

Body:
I am trying to check if a specific value is contained anywhere in a certain column of my dataframe. I am using the following code, where it should clear data containing "0.0". However, it seemed like it is clearing data that does not contain "0.0" as well.

mydataset = mydataset[mydataset['Latitude'].astype(str).str.contains('0.0') == False]

Example of the data as follows. Highlighted in red are data being removed, upon applying the above code.

Body:
If you are using a pandas dataframe you can conditionally drop rows from your dataframe in the following manner:

mydataset = mydataset[str(mydataset.Latitude) != '0.0']

If you are trying to remove all 0 values and not just 0.0 then don't convert to string and it should drop any 0 value.


问:
How to keep click event dynamically created buttons in mvc
i have retrive name of buttons from database those button when i click a
   button i need to show the some report.now i have everything is done.i
   need to know how keep unique id for those buttons and how they worked
   when i click button i need to show report in a separate page...   </p>

```<code>  [HttpGet]
        public ActionResult Estate()
        {

            return View("Estate", new EstateFunc().Estates());

        }

        [HttpPost]
        public ActionResult Estate(int id=0)
        {
            if(id>0)
            {

            }
            return View();

         }
</code>```

答:
With MVC

View:

```<code>@foreach (var item in Model)
{
    <tr>
        <td>@item.Something...</td>
        <td>@item.AnotherThing</td>
        <td>
<a href="@Url.Action("MyAction", "MyController", new { Id = item.Id })" class="btn"></a></td>
    </tr>
}
</code>```

This Razor code will generate as many button as the count of the collection items in your model. Every item in the collection should have unique ID and as you see we put this ID as parameter. So when the user clicks on any of the buttons, the unique ID will tell us which button was clicked (and to which item we should refer to)

Controller:

```<code>public ActionResult MyAction(int id = 0)
        {
            var model = ReportViewModel(id);

            return ReportView(model);
        }

private ReportViewModel(int id)
{
   // Get Report from Database Where Id = id
   // Populate ViewModel from the database data
   // Return reportViewModel;
}
</code>```

EDIT (adding example based on your code)

```<code>   @foreach (var item in Model)
   {
    <div class="floated">

    <a href="@Url.Action("MyAction", "MyController", new { Id = item.Id })"
       class="Estates_button">@item.EstateName</a>

    </div>
    }
</code>```

Body:
i have retrive name of buttons from database those button when i click a
   button i need to show the some report.now i have everything is done.i
   need to know how keep unique id for those buttons and how they worked
   when i click button i need to show report in a separate page...

  [HttpGet]
        public ActionResult Estate()
        {

            return View("Estate", new EstateFunc().Estates());

        }

        [HttpPost]
        public ActionResult Estate(int id=0)
        {
            if(id>0)
            {

            }
            return View();

         }

Body:
With MVC

View:

@foreach (var item in Model)
{
    <tr>
        <td>@item.Something...</td>
        <td>@item.AnotherThing</td>
        <td>
<a href="@Url.Action("MyAction", "MyController", new { Id = item.Id })" class="btn"></a></td>
    </tr>
}

This Razor code will generate as many button as the count of the collection items in your model. Every item in the collection should have unique ID and as you see we put this ID as parameter. So when the user clicks on any of the buttons, the unique ID will tell us which button was clicked (and to which item we should refer to)

Controller:

public ActionResult MyAction(int id = 0)
        {
            var model = ReportViewModel(id);

            return ReportView(model);
        }

private ReportViewModel(int id)
{
   // Get Report from Database Where Id = id
   // Populate ViewModel from the database data
   // Return reportViewModel;
}

EDIT (adding example based on your code)

   @foreach (var item in Model)
   {
    <div class="floated">

    <a href="@Url.Action("MyAction", "MyController", new { Id = item.Id })"
       class="Estates_button">@item.EstateName</a>

    </div>
    }


问:
Why File.OpenRead() appends relative path to the executable file?
Why while using the following code

```<code>string filePath = @"C:\test\upload.pdf"
FileStream fs = File.OpenRead(filePath);
</code>```

raises the following exception?

```<code>The filename, directory name, or volume label syntax is incorrect :
'C:\ConsoleApp\bin\Debug\netcoreapp2.1\C:\test\upload.pdf'
</code>```

From where the C:\ConsoleApp\bin\Debug\netcoreapp2.1\ directory comes from?

Update:
The File.OpenRead() in my case, exists within in an dll & the filePath (C:\test\upload.pdf) is sent via the application that is using the dll.

答:
The string starts with an invisible character, so it's not a valid path. This

```<code>(int)@"C:\test\upload.pdf"[0]
</code>```

Returns

```<code>8234
</code>```

Or hex 202A. That's the LEFT-TO-RIGHT EMBEDDING punctuation character

UPDATE

Raymond Chen posted an article Why is there an invisible U+202A at the start of my file name?.

We saw some time ago that you can, as a last resort, insert the character U+202B (RIGHT-TO-LEFT EMBEDDING) to force text to be interpreted as right-to-left. The converse character is U+202A (LEFT-TO-RIGHT EMBEDDING), which forces text to be interpreted as left-to-right.

The Security dialog box inserts that control character in the file name field in order to ensure that the path components are interpreted in the expected manner. Unfortunately, it also means that if you try to copy the text out of the dialog box, the Unicode formatting control character comes along for a ride. Since the character is normally invisible, it can create all sorts of silent confusion.

(We’re lucky that the confusion was quickly detected by Notepad and the command prompt. But imagine if you had pasted the path into the source code to a C program!)

In the 4 years since that article Notepad got UTF8 support so the character isn't replaced by a question mark. Pasting into the current Windows Console with its incomplete UTF8 support still replaces the character.

Body:
Why while using the following code

string filePath = @"C:\test\upload.pdf"
FileStream fs = File.OpenRead(filePath);

raises the following exception?

The filename, directory name, or volume label syntax is incorrect :
'C:\ConsoleApp\bin\Debug\netcoreapp2.1\C:\test\upload.pdf'

From where the C:\ConsoleApp\bin\Debug\netcoreapp2.1\ directory comes from?

Update:
The File.OpenRead() in my case, exists within in an dll & the filePath (C:\test\upload.pdf) is sent via the application that is using the dll.

Body:
The string starts with an invisible character, so it's not a valid path. This

(int)@"C:\test\upload.pdf"[0]

Returns

8234

Or hex 202A. That's the LEFT-TO-RIGHT EMBEDDING punctuation character

UPDATE

Raymond Chen posted an article Why is there an invisible U+202A at the start of my file name?.

We saw some time ago that you can, as a last resort, insert the character U+202B (RIGHT-TO-LEFT EMBEDDING) to force text to be interpreted as right-to-left. The converse character is U+202A (LEFT-TO-RIGHT EMBEDDING), which forces text to be interpreted as left-to-right.

The Security dialog box inserts that control character in the file name field in order to ensure that the path components are interpreted in the expected manner. Unfortunately, it also means that if you try to copy the text out of the dialog box, the Unicode formatting control character comes along for a ride. Since the character is normally invisible, it can create all sorts of silent confusion.

(We’re lucky that the confusion was quickly detected by Notepad and the command prompt. But imagine if you had pasted the path into the source code to a C program!)

In the 4 years since that article Notepad got UTF8 support so the character isn't replaced by a question mark. Pasting into the current Windows Console with its incomplete UTF8 support still replaces the character.


问:
Making 3rd party API calls from NodeJs as backend and rendering the data received in ReactJs frontend
Since I'm new to API calls, I'm having issues regarding making API calls from backend. I've a form that takes AccessToken from the user. Based on the token received, I've to make an API call to 3rd party API. It should return the roles that the particular user has. The token has to be sent as headers.
How to make the API call if the Frontend is on ReactJs and Backend is running on NodeJs.</p>

答:
Basically you have three entities at work here.

Your Backend - Node

Your Client - React

External Service - Some other service where you are making the call from your backend

Assuming the flow of your application is like this:

Your Client -> (asks for some resource) Your Backend -> (requests an api from external service)

So you can expose an endpoint on Your Backend, which Your client will call and in turn Your Backend will call an External Service using a library like Axios or the inbuilt Fetch API. As soon as Your Backend gets a response from the External Service, you can send the received response to Your Client.

Hope it helps!


问:
Can I move my web app Vuejs to NativeScript-Vue?
Good,
My question is really simple. I have a web project made in Vuejs and I would like to know if there is any way to take this project and to mirror it to NativeScript-Vue in some way.

Thanks and best regards!

答: There isn't an automated way to migrate your app. The templates should be completely rewritten as the mobile world has different UI components and concepts. Your scripts and styles, for the most part, should work the same way. You will need to figure out how to do the routing as the default vue.js router is not supported. You can check the manual routing article fore more information.</p>


问:
How to add a second column of values in the properties panel?
I created a property panel that displays the properties of the selected item. The property panel contains a category, property names and their values. I want to add a second column of values, but I do not know how to do this.
Here is my extension code.</p>

答:
You can extend the original PropertyPanel.prototype.displayProperty and create another div right next to the default one:

```<code>YourPropertyPanel.prototype.displayProperty = function (property, parent, options) {
    Autodesk.Viewing.Extensions.ViewerPropertyPanel.prototype.displayProperty .call(this, property, parent, options); //if you'd like to keep the existing column

    var yourSecondColumn= document.createElement('div');
    ...//set up your column
    parent.appendChild(yourSecondColumn)
})
</code>```

Body:
You can extend the original PropertyPanel.prototype.displayProperty and create another div right next to the default one:

YourPropertyPanel.prototype.displayProperty = function (property, parent, options) {
    Autodesk.Viewing.Extensions.ViewerPropertyPanel.prototype.displayProperty .call(this, property, parent, options); //if you'd like to keep the existing column

    var yourSecondColumn= document.createElement('div');
    ...//set up your column
    parent.appendChild(yourSecondColumn)
})


问:
Is /dev/random considered truly random?
For instance, could it be used to generate a one-time pad key?

Also, what are its sources and how could it be used to generate a random number between x and y?

答:
The only thing in this universe that can be considered truly is one based on quantum effects. Common example is radioactive decay. For certain atoms you can be sure only about half-life, but you can't be sure which nucleus will break up next.

About /dev/random - it depends on implementation. In Linux it uses as entropy sources:

The Linux kernel generates entropy
  from keyboard timings, mouse
  movements, and IDE timings and makes
  the random character data available to
  other operating system processes
  through the special files /dev/random
  and /dev/urandom.

Wiki

It means that it is better than algorithmic random generators, but it is not perfect as well. The entropy may not be distributed randomly and can be biased.

This was philosophy. Practice is that on Linux /dev/random is random enough for vast majority of tasks.

There are implementations of random generators that have more entropy sources, including noise on audio inputs, CPU temperature sensors etc. Anyway they are not true.

There is interesting site where you can get Genuine random numbers, generated by radioactive decay.

Title: Is /dev/random considered truly random?


问:
What is the best practice for console logging, if jenkins plugin dependency is using slf4j?
I am developing a Jenkins plugin which is using another library. The plugin is a wrapper, which configures a library and uses it. An idea is similar to violation-comments-to-github-plugin. Little chances to change logging in the library. At Jenkins side I have TaskListener.logger: PrintStream . But the lib is logging useful info through SLF4J.

What are the best practices to deal with this situation? Maybe do you know some well-written plugin as an example?

答:
I don't know best what is best practice for logging, but I created an adapter which does the job at least. </p>

```<code>override fun perform(run: Run<*, *>, workspace: FilePath, launcher: Launcher, listener: TaskListener) {
    val logger = SLF4JOutputStreamAdapter(listener.logger, logLevel.levelInt)

    val builder = AutoMergerBuilder()
            .logger(logger) // I had implement this method in the library
}
</code>```

Body:
I don't know best what is best practice for logging, but I created an adapter which does the job at least.

override fun perform(run: Run<*, *>, workspace: FilePath, launcher: Launcher, listener: TaskListener) {
    val logger = SLF4JOutputStreamAdapter(listener.logger, logLevel.levelInt)

    val builder = AutoMergerBuilder()
            .logger(logger) // I had implement this method in the library
}


问:
Django user.has_perm return false
I got some strange issue when user.has_perm always return true, even when permission is for sure in table.
Maybe someone got like this before?
Seams like issue only in last versions

Test show issue is below:

```<code>import django
import datetime
django.setup()

from django.contrib.auth.models import User

u=User.objects.get(pk=177)

print("version %s" % str(django.VERSION))
print("1: %s" %str(u.has_perm('not_show_tos')))

from django.contrib.auth.models import Permission
permissions = Permission.objects.filter(user=u)

sorted_list_of_permissions = sorted(list(permissions))
print("2:%s " % str("not_show_tos" in sorted_list_of_permissions));
for i in sorted_list_of_permissions:
  print( str(i.codename))
  print("%s" %str(u.has_perm(i.codename)))
  print("\n")

p=Permission.objects.get(codename='not_show_tos');
print("4 %s " % str(p))
print("5 %s " % str(p in sorted_list_of_permissions))
print("6 %s " % str(u.has_perm(p)))
</code>```

Test result

```<code> python3 /tmp/test.py
signals init done.
version (2, 0, 6, 'final', 0)
1: False
2:False
not_show_tos
False

4 sessions | session | Not Show Tos Page
5 True
6 False
</code>```

答:
The string you pass to has_perm should be in the format "<app_label>.<permission.codename>". That is: u.has_perm('sessions.not_show_tos')

From the django docs:

has_perm(perm, obj=None)

Returns True if the user has the specified permission, where perm is in the format "<app_label>.<permission.codename>". (see documentation on permissions). If the user is inactive, this method will always return False.

If obj is passed in, this method won’t check for a permission for the model, but for this specific object.

https://docs.djangoproject.com/en/2.2/ref/contrib/auth/#django.contrib.auth.models.User.has_perm

Title: Django user.has_perm return false

Body:
I got some strange issue when user.has_perm always return true, even when permission is for sure in table.
Maybe someone got like this before?
Seams like issue only in last versions

Test show issue is below:

import django
import datetime
django.setup()

from django.contrib.auth.models import User

u=User.objects.get(pk=177)

print("version %s" % str(django.VERSION))
print("1: %s" %str(u.has_perm('not_show_tos')))

from django.contrib.auth.models import Permission
permissions = Permission.objects.filter(user=u)

sorted_list_of_permissions = sorted(list(permissions))
print("2:%s " % str("not_show_tos" in sorted_list_of_permissions));
for i in sorted_list_of_permissions:
  print( str(i.codename))
  print("%s" %str(u.has_perm(i.codename)))
  print("\n")

p=Permission.objects.get(codename='not_show_tos');
print("4 %s " % str(p))
print("5 %s " % str(p in sorted_list_of_permissions))
print("6 %s " % str(u.has_perm(p)))

Test result

 python3 /tmp/test.py
signals init done.
version (2, 0, 6, 'final', 0)
1: False
2:False
not_show_tos
False

4 sessions | session | Not Show Tos Page
5 True
6 False


问:
A help in concept and a database query question (Django/Python)
I am trying to build a kind of news website for learning purposes.

```<code>class NewsCategory(models.Model):
    category = models.CharField(max_length=50)
</code>```

Note: A category can be Soccer, Tennis, business ... User can register to different news category. This choice will be saved in their preferences.

```<code>class Profile(models.Model):
    user = models.ForeignKey(User, unique=True)
    gender = models.CharField(max_length=1,blank=True)
    preference = models.ManyToManyField(NewsCategory)
</code>```

I am currently stuck on how to update the preference list of each user (the list that specifies in which categories he is interested in.)

View:

```<code>category = [(item.category) for item in NewsCategory.objects.all()]
</code>```

and then I am sending the category to the template below

template:

```<code><div id="c_b">
    {% for c in category %}
        <input type="checkbox" name="category[]" value="{{c}}">
        <label for="{{c}}">{{c}}</label>
    {% endfor %}
</div>
</code>```

Questions:

What is the best way to add the checked tag next to the checkboxes that are already saved in the user's preference when I display the template.

I though of getting all the preferences users are registered for: saved_preference = user.preference.all() and then checking for each item in category if it is in saved_preference

I am also blanking out on the way to actually write that into code, and whether this should be done in the view or the template.

What is a good way to update the user preference list?

I was planning on running user.preference.clear() and then going through every item in the submitted form and running user.preference.add(the_new_preference)

答: You should learn about forms and model forms in django. It would be the best way for both adding and changing. Forms will do the most of job for you.</p>

Body:
I am trying to build a kind of news website for learning purposes.

class NewsCategory(models.Model):
    category = models.CharField(max_length=50)

Note: A category can be Soccer, Tennis, business ... User can register to different news category. This choice will be saved in their preferences.

class Profile(models.Model):
    user = models.ForeignKey(User, unique=True)
    gender = models.CharField(max_length=1,blank=True)
    preference = models.ManyToManyField(NewsCategory)

I am currently stuck on how to update the preference list of each user (the list that specifies in which categories he is interested in.)

View:

category = [(item.category) for item in NewsCategory.objects.all()]

and then I am sending the category to the template below

template:

    {% for c in category %}
        <input type="checkbox" name="category[]" value="{{c}}">
        {{c}}
    {% endfor %}

Questions:

What is the best way to add the checked tag next to the checkboxes that are already saved in the user's preference when I display the template.

I though of getting all the preferences users are registered for: saved_preference = user.preference.all() and then checking for each item in category if it is in saved_preference

I am also blanking out on the way to actually write that into code, and whether this should be done in the view or the template.

What is a good way to update the user preference list?

I was planning on running user.preference.clear() and then going through every item in the submitted form and running user.preference.add(the_new_preference)


问:
How to distinguish if styled component was created with React component or with another styled component / native tag
I have a very sophisticated component, and I want to prevent passing React components and styled component that were created with React components there. The only components I want to allow are 1) other "simple" styled components 2) native tags (like div).
For example:

```<code>function SophisticatedComponent({
  element,
}) {
  if (isReactComponent(element)) {
    throw new Error('React components are forbidden!');
  }
  ...
}

function ReactComponent() {
  return (
    <div/>;
  );
}

<SophisticatedComponent element={<ReactComponent/>}/> // THROW

<SophisticatedComponent element={<div><ReactComponent/></div>}/> // OK

const StyledComponent = styled.div``;
<SophisticatedComponent element={<StyledComponent><ReactComponent/></StyledComponent>}/> // OK

const StyledReactComponent = styled(ReactComponent)``;
<SophisticatedComponent element={<StyledReactComponent/>}/> // THROW
</code>```

How can I write this isReactComponent function to distinguish between React components and styled components?

答:
This is the function:</p>

```<code>function isReactComponent({type}) {
  if (typeof type === 'string') { // <div><ReactComponent/></div>
    return false;
  }
  if (typeof type === 'object') { // <ReactComponent/>
    return true;
  }
  if (typeof type === 'function' && typeof type.target === 'string') { // <StyledComponent><ReactComponent/></StyledComponent>
    return false;
  }
  if (typeof type === 'function' && typeof type.target === 'object') { // <StyledReactComponent/>
    return true;
  }
}
</code>```

Body:
I have a very sophisticated component, and I want to prevent passing React components and styled component that were created with React components there. The only components I want to allow are 1) other "simple" styled components 2) native tags (like div).
For example:

function SophisticatedComponent({
  element,
}) {
  if (isReactComponent(element)) {
    throw new Error('React components are forbidden!');
  }
  ...
}

function ReactComponent() {
  return (

;
  );
}

<SophisticatedComponent element={<ReactComponent/>}/> // THROW

<SophisticatedComponent element={
<ReactComponent/>
}/> // OK

const StyledComponent = styled.div``;
<SophisticatedComponent element={}/> // OK

const StyledReactComponent = styled(ReactComponent)``;
<SophisticatedComponent element={

Body:
This is the function:

function isReactComponent({type}) {
  if (typeof type === 'string') { // <div><ReactComponent/></div>
    return false;
  }
  if (typeof type === 'object') { // <ReactComponent/>
    return true;
  }
  if (typeof type === 'function' && typeof type.target === 'string') { // <StyledComponent><ReactComponent/></StyledComponent>
    return false;
  }
  if (typeof type === 'function' && typeof type.target === 'object') { // <StyledReactComponent/>
    return true;
  }
}


问:
How to get a response after using stream functionality?
So, I'm getting an error "Cannot set headers after they are sent to the client". I get that my code res.status(200).send(OK(fileObj, null, req)); is synchronous. I'm not sure how to get a response after all my streams are ready.

```<code>    try {

        const fileObj = [];

        const stream =  await minioClient.listObjects(bucket, '', true);

        await stream.on('data', async (obj, error) => {

            await fileObj.push(obj);

            if (error) {

                console.log(error);

            }

            res.status(200).send(OK(fileObj, null, req));
        });

        stream.on('error', function (err) {

            console.log(err);

        });
    }

    catch (e) {

        console.log(e);

    }
</code>```

Expected result: It shouldn't show me "Cannot set headers after they are sent to the client" response.

答:
Probably you must send response on stream end event.</p>

```<code>stream.once('end', _=> res.status(200).send('OK'));
</code>```

Body:
So, I'm getting an error "Cannot set headers after they are sent to the client". I get that my code res.status(200).send(OK(fileObj, null, req)); is synchronous. I'm not sure how to get a response after all my streams are ready.

    try {

        const fileObj = [];

        const stream =  await minioClient.listObjects(bucket, '', true);

        await stream.on('data', async (obj, error) => {

            await fileObj.push(obj);

            if (error) {

                console.log(error);

            }

            res.status(200).send(OK(fileObj, null, req));
        });

        stream.on('error', function (err) {

            console.log(err);

        });
    }

    catch (e) {

        console.log(e);

    }

Expected result: It shouldn't show me "Cannot set headers after they are sent to the client" response.

Body:
Probably you must send response on stream end event.

stream.once('end', _=> res.status(200).send('OK'));


答:
As you said already a simple recursion will do:

def put_tabs(d, level=0):
    rv = []
    prefix = '\t' * level
    for key in d:
        rv.append(prefix+key)
        if type(d[key]) == dict and len(d[key]) > 0:
            rv.extend(put_tabs(d[key], level=level+1))

    return rv

d = {"step1": {}, "step2": {"step3": {"step4": {}}, "step7": {}}}
print(put_tabs(d))
# ['step1', 'step2', '\tstep3', '\t\tstep4', '\tstep7']
```

Title: Iterating over keys of nested dictionary and adding tabs

Body:
I have a nested dictionary like this {"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}},Now i need to recursively iterate over the nested dictionary and create a list of keys of nested dictionary with tabs prepend to it.

new_d={"step1": {}, "step2": {"step3": {"step4": {}},'step7':{}}}
other_list=[]
child=False
tabb='\t'
def put_tabs(d):
  global tabb,child
  for k, v in d.iteritems():
      if v:
          if child:
              other_list.append("{0}{1}".format(tabb,k))
              tabb+='\t'
          else:
              other_list.append("{0}".format(k))
          child=True
          put_tabs(v)
      else:
          if child:
              other_list.append("{0}{1}".format(tabb,k))

          else:
              other_list.append("{0}:".format(k))
          child=False
put_tabs(new_d)
print other_list

# Expected output ['step2', '\tstep7', '\tstep3', '\t\tstep4', 'step1:']
# current ouput ['step2', '\tstep7', 'step3', '\t\step4', 'step1:']


问:
How to get screen size of monitor in multi-monitor setup in UWP C#
I am using below C# code to get the screen size of the monitor in UWP.

```<code>var displayInformation = DisplayInformation.GetForCurrentView();
var screenSize = new Size((int)displayInformation.ScreenWidthInRawPixels,
                                      (int)displayInformation.ScreenHeightInRawPixels);
</code>```

But the problem is it returns first monitor resolution. I have two monitors and I need to screen size of the monitor where the app is run. not first monitor. If the app runs on the second monitor then I need screen size of the second monitor instead of the first monitor. My monitor size is different.

How can I solve this puzzle?

答:
That should actually be the behavior you will be getting - once you move your app to another screen, DisplayInformation properties will start returning values for that given screen.

I have tested it locally as well - you don't even have to get a new instance via GetForCurrentView - even if you just have one instance, calling ScreenWidthInRawPixels and similar properties when your app moves to the second screen, you will be getting the correct values.

Body:
I am using below C# code to get the screen size of the monitor in UWP.

var displayInformation = DisplayInformation.GetForCurrentView();
var screenSize = new Size((int)displayInformation.ScreenWidthInRawPixels,
                                      (int)displayInformation.ScreenHeightInRawPixels);

But the problem is it returns first monitor resolution. I have two monitors and I need to screen size of the monitor where the app is run. not first monitor. If the app runs on the second monitor then I need screen size of the second monitor instead of the first monitor. My monitor size is different.

How can I solve this puzzle?


问:
Collection view inside table view
I have the following problem.
In my project I have a table view with multiple sections and one row in every section. Inside row I have a collection view.
Collection view items count depending on section in which the collection is located.But I do not understand how to access section number when I call func numberOfItemsInSection for collection view.

Here is my code:

ViewController.swift

```<code>func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}
</code>```

TableCell.swift

```<code>func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //TODO ?????? How can i get here section of table view
}
</code>```

Thanks!

答:
Here you can use object oriented approach, in Your tableview cell create a variable tableSectionNumber. Like

```<code>class YourCell: UITableViewCell {
    public var tableViewSectionNumber: Int = 0;
....
</code>```

Now here in collectionView numberOfItemsInSection method, you can access it

```<code> func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//TODO ?????? How can i get here section of table view
  self.tableViewSectionNumber // its here
 }
</code>```

Now you can set this value in the cell in your ViewController, when you are populating the cell in TableView cellForRowItem method, Like

```<code>func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell
    cell.tableViewSectionNumber = indexPath.section // here you set the section number in cell
}
</code>```

Title: Collection view inside table view

Body:
I have the following problem.
In my project I have a table view with multiple sections and one row in every section. Inside row I have a collection view.
Collection view items count depending on section in which the collection is located.But I do not understand how to access section number when I call func numberOfItemsInSection for collection view.

Here is my code:

ViewController.swift

func numberOfSections(in tableView: UITableView) -> Int {
return data.count
}

TableCell.swift

func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
    //TODO ?????? How can i get here section of table view
}

Thanks!

Body:
Here you can use object oriented approach, in Your tableview cell create a variable tableSectionNumber. Like

class YourCell: UITableViewCell {
    public var tableViewSectionNumber: Int = 0;
....

Now here in collectionView numberOfItemsInSection method, you can access it

 func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
//TODO ?????? How can i get here section of table view
  self.tableViewSectionNumber // its here
 }

Now you can set this value in the cell in your ViewController, when you are populating the cell in TableView cellForRowItem method, Like

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

    let cell = tableView.dequeueReusableCell(withIdentifier: cellIdentifier, for: indexPath) as! YourCell
    cell.tableViewSectionNumber = indexPath.section // here you set the section number in cell
}


问:
Get filename and path from URI from mediastore
I have an onActivityResult returning from an mediastore image selection which I can get a URI for an image using the following:

```<code>Uri selectedImage = data.getData();
</code>```

Converting this to a string gives this:

```<code>content://media/external/images/media/47
</code>```

Or to a path gives:

```<code>/external/images/media/47
</code>```

However I can't seem to find a way to convert this into an absolute path, as I want to load the image into a bitmap without having to copy it somewhere. I know this can be done using the URI and content resolver, but this seems to break on rebooting of the phone, I guess MediaStore doesn't keep its numbering the same between reboots.

答:
To get any sort of file path use this :  </p>

```<code>/*
 * Copyright (C) 2007-2008 OpenIntents.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yourpackage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;

/**
 * @author Peli
 * @author paulburke (ipaulpro)
 * @version 2013-12-11
 */
public class FileUtils {
    private FileUtils() {
    } //private constructor to enforce Singleton pattern

    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = true; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     * null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * Get a file path from a Uri. This will quickGet the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

//                if ("primary".equalsIgnoreCase(type)) {
//                    return Environment.getExternalStorageDirectory() + "/" + split[1];
//                }
                return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                try {
                    final String id = DocumentsContract.getDocumentId(uri);
                    Log.d(TAG, "getPath: id= " + id);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (Exception e){
                    e.printStackTrace();
                    List<String> segments = uri.getPathSegments();
                    if(segments.size() > 1) {
                        String rawPath = segments.get(1);
                        if(!rawPath.startsWith("/")){
                            return rawPath.substring(rawPath.indexOf("/"));
                        }else {
                            return rawPath;
                        }
                    }
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    /**
     * Get the file size in a human-readable string.
     *
     * @param size
     * @return
     * @author paulburke
     */
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    /**
     * Attempt to retrieve the thumbnail of given File from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param file
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @param mimeType
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to quickGet thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    /**
     * File and folder comparator. TODO Expose sorting option method
     *
     * @author paulburke
     */
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

    /**
     * File (not directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Folder (directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Get the Intent for selecting content to be used in an Intent Chooser.
     *
     * @return The intent for opening a file with Intent.createChooser()
     * @author paulburke
     */
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}
</code>```

Body:
I have an onActivityResult returning from an mediastore image selection which I can get a URI for an image using the following:

Uri selectedImage = data.getData();

Converting this to a string gives this:

content://media/external/images/media/47

Or to a path gives:

/external/images/media/47

However I can't seem to find a way to convert this into an absolute path, as I want to load the image into a bitmap without having to copy it somewhere. I know this can be done using the URI and content resolver, but this seems to break on rebooting of the phone, I guess MediaStore doesn't keep its numbering the same between reboots.

Body:
To get any sort of file path use this :

/*
 * Copyright (C) 2007-2008 OpenIntents.org
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.yourpackage;

import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.database.DatabaseUtils;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.DocumentsContract;
import android.provider.MediaStore;
import android.util.Log;
import android.webkit.MimeTypeMap;

import java.io.File;
import java.io.FileFilter;
import java.text.DecimalFormat;
import java.util.Comparator;
import java.util.List;

/**
 * @author Peli
 * @author paulburke (ipaulpro)
 * @version 2013-12-11
 */
public class FileUtils {
    private FileUtils() {
    } //private constructor to enforce Singleton pattern

    /**
     * TAG for log messages.
     */
    static final String TAG = "FileUtils";
    private static final boolean DEBUG = true; // Set to true to enable logging

    public static final String MIME_TYPE_AUDIO = "audio/*";
    public static final String MIME_TYPE_TEXT = "text/*";
    public static final String MIME_TYPE_IMAGE = "image/*";
    public static final String MIME_TYPE_VIDEO = "video/*";
    public static final String MIME_TYPE_APP = "application/*";

    public static final String HIDDEN_PREFIX = ".";

    /**
     * Gets the extension of a file name, like ".png" or ".jpg".
     *
     * @param uri
     * @return Extension including the dot("."); "" if there is no extension;
     * null if uri was null.
     */
    public static String getExtension(String uri) {
        if (uri == null) {
            return null;
        }

        int dot = uri.lastIndexOf(".");
        if (dot >= 0) {
            return uri.substring(dot);
        } else {
            // No extension.
            return "";
        }
    }

    /**
     * @return Whether the URI is a local one.
     */
    public static boolean isLocal(String url) {
        if (url != null && !url.startsWith("http://") && !url.startsWith("https://")) {
            return true;
        }
        return false;
    }

    /**
     * @return True if Uri is a MediaStore Uri.
     * @author paulburke
     */
    public static boolean isMediaUri(Uri uri) {
        return "media".equalsIgnoreCase(uri.getAuthority());
    }

    /**
     * Convert File into Uri.
     *
     * @param file
     * @return uri
     */
    public static Uri getUri(File file) {
        if (file != null) {
            return Uri.fromFile(file);
        }
        return null;
    }

    /**
     * Returns the path only (without file name).
     *
     * @param file
     * @return
     */
    public static File getPathWithoutFilename(File file) {
        if (file != null) {
            if (file.isDirectory()) {
                // no file to be split off. Return everything
                return file;
            } else {
                String filename = file.getName();
                String filepath = file.getAbsolutePath();

                // Construct path without file name.
                String pathwithoutname = filepath.substring(0,
                        filepath.length() - filename.length());
                if (pathwithoutname.endsWith("/")) {
                    pathwithoutname = pathwithoutname.substring(0, pathwithoutname.length() - 1);
                }
                return new File(pathwithoutname);
            }
        }
        return null;
    }

    /**
     * @return The MIME type for the given file.
     */
    public static String getMimeType(File file) {

        String extension = getExtension(file.getName());

        if (extension.length() > 0)
            return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.substring(1));

        return "application/octet-stream";
    }

    /**
     * @return The MIME type for the give Uri.
     */
    public static String getMimeType(Context context, Uri uri) {
        File file = new File(getPath(context, uri));
        return getMimeType(file);
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is {@link LocalStorageProvider}.
     * @author paulburke
     */
    public static boolean isLocalStorageDocument(Uri uri) {
        return LocalStorageProvider.AUTHORITY.equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is ExternalStorageProvider.
     * @author paulburke
     */
    public static boolean isExternalStorageDocument(Uri uri) {
        return "com.android.externalstorage.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is DownloadsProvider.
     * @author paulburke
     */
    public static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is MediaProvider.
     * @author paulburke
     */
    public static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * @param uri The Uri to check.
     * @return Whether the Uri authority is Google Photos.
     */
    public static boolean isGooglePhotosUri(Uri uri) {
        return "com.google.android.apps.photos.content".equals(uri.getAuthority());
    }

    /**
     * Get the value of the data column for this Uri. This is useful for
     * MediaStore Uris, and other file-based ContentProviders.
     *
     * @param context       The context.
     * @param uri           The Uri to query.
     * @param selection     (Optional) Filter used in the query.
     * @param selectionArgs (Optional) Selection arguments used in the query.
     * @return The value of the _data column, which is typically a file path.
     * @author paulburke
     */
    public static String getDataColumn(Context context, Uri uri, String selection,
                                       String[] selectionArgs) {

        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {
                column
        };

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                    null);
            if (cursor != null && cursor.moveToFirst()) {
                if (DEBUG)
                    DatabaseUtils.dumpCursor(cursor);

                final int column_index = cursor.getColumnIndexOrThrow(column);
                return cursor.getString(column_index);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (cursor != null)
                cursor.close();
        }
        return null;
    }

    /**
     * Get a file path from a Uri. This will quickGet the the path for Storage Access
     * Framework Documents, as well as the _data field for the MediaStore and
     * other file-based ContentProviders.<br>
     * <br>
     * Callers should check whether the path is local before assuming it
     * represents a local file.
     *
     * @param context The context.
     * @param uri     The Uri to query.
     * @author paulburke
     * @see #isLocal(String)
     * @see #getFile(Context, Uri)
     */
    public static String getPath(final Context context, final Uri uri) {

        if (DEBUG)
            Log.d(TAG + " File -",
                    "Authority: " + uri.getAuthority() +
                            ", Fragment: " + uri.getFragment() +
                            ", Port: " + uri.getPort() +
                            ", Query: " + uri.getQuery() +
                            ", Scheme: " + uri.getScheme() +
                            ", Host: " + uri.getHost() +
                            ", Segments: " + uri.getPathSegments().toString()
            );
        // DocumentProvider
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT && DocumentsContract.isDocumentUri(context, uri)) {
            // LocalStorageProvider
            if (isLocalStorageDocument(uri)) {
                // The path is the id
                return DocumentsContract.getDocumentId(uri);
            }
            // ExternalStorageProvider
            else if (isExternalStorageDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

//                if ("primary".equalsIgnoreCase(type)) {
//                    return Environment.getExternalStorageDirectory() + "/" + split[1];
//                }
                return Environment.getExternalStorageDirectory() + "/" + split[1];

                // TODO handle non-primary volumes
            }
            // DownloadsProvider
            else if (isDownloadsDocument(uri)) {
                try {
                    final String id = DocumentsContract.getDocumentId(uri);
                    Log.d(TAG, "getPath: id= " + id);
                    final Uri contentUri = ContentUris.withAppendedId(Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));
                    return getDataColumn(context, contentUri, null, null);
                }catch (Exception e){
                    e.printStackTrace();
                    List<String> segments = uri.getPathSegments();
                    if(segments.size() > 1) {
                        String rawPath = segments.get(1);
                        if(!rawPath.startsWith("/")){
                            return rawPath.substring(rawPath.indexOf("/"));
                        }else {
                            return rawPath;
                        }
                    }
                }
            }
            // MediaProvider
            else if (isMediaDocument(uri)) {
                final String docId = DocumentsContract.getDocumentId(uri);
                final String[] split = docId.split(":");
                final String type = split[0];

                Uri contentUri = null;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                }

                final String selection = "_id=?";
                final String[] selectionArgs = new String[]{
                        split[1]
                };

                return getDataColumn(context, contentUri, selection, selectionArgs);
            }
        }
        // MediaStore (and general)
        else if ("content".equalsIgnoreCase(uri.getScheme())) {

            // Return the remote address
            if (isGooglePhotosUri(uri))
                return uri.getLastPathSegment();

            return getDataColumn(context, uri, null, null);
        }
        // File
        else if ("file".equalsIgnoreCase(uri.getScheme())) {
            return uri.getPath();
        }

        return null;
    }

    /**
     * Convert Uri into File, if possible.
     *
     * @return file A local file that the Uri was pointing to, or null if the
     * Uri is unsupported or pointed to a remote resource.
     * @author paulburke
     * @see #getPath(Context, Uri)
     */
    public static File getFile(Context context, Uri uri) {
        if (uri != null) {
            String path = getPath(context, uri);
            if (path != null && isLocal(path)) {
                return new File(path);
            }
        }
        return null;
    }

    /**
     * Get the file size in a human-readable string.
     *
     * @param size
     * @return
     * @author paulburke
     */
    public static String getReadableFileSize(int size) {
        final int BYTES_IN_KILOBYTES = 1024;
        final DecimalFormat dec = new DecimalFormat("###.#");
        final String KILOBYTES = " KB";
        final String MEGABYTES = " MB";
        final String GIGABYTES = " GB";
        float fileSize = 0;
        String suffix = KILOBYTES;

        if (size > BYTES_IN_KILOBYTES) {
            fileSize = size / BYTES_IN_KILOBYTES;
            if (fileSize > BYTES_IN_KILOBYTES) {
                fileSize = fileSize / BYTES_IN_KILOBYTES;
                if (fileSize > BYTES_IN_KILOBYTES) {
                    fileSize = fileSize / BYTES_IN_KILOBYTES;
                    suffix = GIGABYTES;
                } else {
                    suffix = MEGABYTES;
                }
            }
        }
        return String.valueOf(dec.format(fileSize) + suffix);
    }

    /**
     * Attempt to retrieve the thumbnail of given File from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param file
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, File file) {
        return getThumbnail(context, getUri(file), getMimeType(file));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri) {
        return getThumbnail(context, uri, getMimeType(context, uri));
    }

    /**
     * Attempt to retrieve the thumbnail of given Uri from the MediaStore. This
     * should not be called on the UI thread.
     *
     * @param context
     * @param uri
     * @param mimeType
     * @return
     * @author paulburke
     */
    public static Bitmap getThumbnail(Context context, Uri uri, String mimeType) {
        if (DEBUG)
            Log.d(TAG, "Attempting to quickGet thumbnail");

        if (!isMediaUri(uri)) {
            Log.e(TAG, "You can only retrieve thumbnails for images and videos.");
            return null;
        }

        Bitmap bm = null;
        if (uri != null) {
            final ContentResolver resolver = context.getContentResolver();
            Cursor cursor = null;
            try {
                cursor = resolver.query(uri, null, null, null, null);
                if (cursor.moveToFirst()) {
                    final int id = cursor.getInt(0);
                    if (DEBUG)
                        Log.d(TAG, "Got thumb ID: " + id);

                    if (mimeType.contains("video")) {
                        bm = MediaStore.Video.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Video.Thumbnails.MINI_KIND,
                                null);
                    } else if (mimeType.contains(FileUtils.MIME_TYPE_IMAGE)) {
                        bm = MediaStore.Images.Thumbnails.getThumbnail(
                                resolver,
                                id,
                                MediaStore.Images.Thumbnails.MINI_KIND,
                                null);
                    }
                }
            } catch (Exception e) {
                if (DEBUG)
                    Log.e(TAG, "getThumbnail", e);
            } finally {
                if (cursor != null)
                    cursor.close();
            }
        }
        return bm;
    }

    /**
     * File and folder comparator. TODO Expose sorting option method
     *
     * @author paulburke
     */
    public static Comparator<File> sComparator = new Comparator<File>() {
        @Override
        public int compare(File f1, File f2) {
            // Sort alphabetically by lower case, which is much cleaner
            return f1.getName().toLowerCase().compareTo(
                    f2.getName().toLowerCase());
        }
    };

    /**
     * File (not directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sFileFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return files only (not directories) and skip hidden files
            return file.isFile() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Folder (directories) filter.
     *
     * @author paulburke
     */
    public static FileFilter sDirFilter = new FileFilter() {
        @Override
        public boolean accept(File file) {
            final String fileName = file.getName();
            // Return directories only and skip hidden directories
            return file.isDirectory() && !fileName.startsWith(HIDDEN_PREFIX);
        }
    };

    /**
     * Get the Intent for selecting content to be used in an Intent Chooser.
     *
     * @return The intent for opening a file with Intent.createChooser()
     * @author paulburke
     */
    public static Intent createGetContentIntent() {
        // Implicitly allow the user to select a particular kind of data
        final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        // The MIME data type filter
        intent.setType("*/*");
        // Only return URIs that can be opened with ContentResolver
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        return intent;
    }
}


问:
How to successfully combine slick read action and then slick write action in for comprehension
Consider I have the following tables: A, B and AB.
Tables AB is a link table between A and B.

When I execute a simple insertOrUpdate action, it succeeds. I have 1 row inserted in the table.

```<code>val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
Await.result(db.run(ab.insertOrUpdate(ABLink(1,1)),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 1
</code>```

But when I read from table A and B, get the ids and then insertorUpdate into table AB using for comprehension, The row is not inserted. The program completes without any errors.

```<code>val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
val action = for {
aId <- a.map(_.id).result.headOption
bId <- b.map(_.id).result.headOption
}
yield ab.insertOrUpdate(ABLink(aId.get,bId.get))
Await.result(db.run(action),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 0
</code>```

Can someone throw light on this behavior?

答:
Because map operation is performed on the last value of the for comprehension, the insertOrUpdate Statement wasn't executed by run. When I use flatMap , it works.

When using Map. it creates a nested DBIOAction.
The inner sqlAction is not executed.

DBIOAction[FixedSqlAction[Int, NoStream, Effect.Write], NoStream, Effect.Read with Effect.Read]

When using flatMap, it creats a flattend DBIOAction which gets executed.

DBIOAction[Int, NoStream, Effect.Read with Effect.Read with Effect.Write]

```<code>val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
val action = for {
aId <- a.map(_.id).result.headOption
bId <- b.map(_.id).result.headOption
}
yield ABLink(aId.get,bId.get)
Await.result(db.run(action.flatMap(ab.insertOrUpdate(_)),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 1

</code>```

Body:
Consider I have the following tables: A, B and AB.
Tables AB is a link table between A and B.

When I execute a simple insertOrUpdate action, it succeeds. I have 1 row inserted in the table.

val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
Await.result(db.run(ab.insertOrUpdate(ABLink(1,1)),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 1

But when I read from table A and B, get the ids and then insertorUpdate into table AB using for comprehension, The row is not inserted. The program completes without any errors.

val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
val action = for {
aId <- a.map(_.id).result.headOption
bId <- b.map(_.id).result.headOption
}
yield ab.insertOrUpdate(ABLink(aId.get,bId.get))
Await.result(db.run(action),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 0

Can someone throw light on this behavior?

Body:
Because map operation is performed on the last value of the for comprehension, the insertOrUpdate Statement wasn't executed by run. When I use flatMap , it works.

When using Map. it creates a nested DBIOAction.
The inner sqlAction is not executed.

DBIOAction[FixedSqlAction[Int, NoStream, Effect.Write], NoStream, Effect.Read with Effect.Read]

When using flatMap, it creats a flattend DBIOAction which gets executed.

DBIOAction[Int, NoStream, Effect.Read with Effect.Read with Effect.Write]

val a = TableQuery[A]
val b = TableQuery[B]
val ab = TableQuery[AB]
val action = for {
aId <- a.map(_.id).result.headOption
bId <- b.map(_.id).result.headOption
}
yield ABLink(aId.get,bId.get)
Await.result(db.run(action.flatMap(ab.insertOrUpdate(_)),Duration.Inf)
println(Await.result(db.run(ab.length.result, Duration.Inf)))
//prints 1