How to manage string url parameter properly (primary key issue) - django

I'm trying to manage folder navigation in django 1.6, my goals is to get something like the url pattern you can see on Dropbox website. The url looks like to : 'Home/Folder/Subfolder'.
I've an issue when there is two folders with the same name but with a different primary key of course. These folders are located in a different directory.
First, in my template, i was sending the name of the folder as a get parameter. In order to get the right folder object in my view when i had two folder with the same name, i have changed my url conf passing the folder pk as a post data (similar to this answer : https://stackoverflow.com/a/6118735/2112198).
It works, but i would like to find a better way to achieve this. Could i pass the pk as a get parameter and rewrite the url next in the view to get only the folder name in the url browser ?

If you need two identical urls to represent two different objects then your url scheme is conceptually flawed.
With the caveat... clearly this works for Dropbox. It is worth thinking about why this works: in Dropbox you are logged in as a specific user. Each user has their own folder structure, but a user can't have two folders with the same name.
i.e. there is a hidden variable (user id) that is added to the folder path in order to locate a unique object.
Alternatively, if you are just trying to work around this simpler problem:
Home/Documents/Work
Home/Pictures/Work
i.e. two folders named Work then you just need to consider the whole path like Pictures/Work vs Documents/Work in order to disambiguate them.

Related

How to Make Relative Href Work in SvelteKit?

I want to build a Web app with SvelteKit with one page listing all items (with potential search query parameters), and then one page for each individual item. If I had to build this the old school way with everything generated in the backend, my paths would be /items/ for a the listing of items, and /items/123 for item 123, etc. That is, to go to the page of item 123, a link will with href="123" will work no matter if you are currently at the index (/items/) or at the page of one particuler item (/items/[id]).
With SvelteKit, if I create files routes/items/index.svelte and routes/items/[id].svelte, then routes/items/index.svelte will have path /items, without a trailing slash, and as a result a link with href="123" will lead to /123, resulting in a "not found" error.
This same link will work however from the page of an individual item, say, /items/456.
This is radically different from what you would have in the traditional HTML model, where a link from /items/ (or /items/index.html) would work the same as a link from /items/[id].html.
Now in svelte.config.js there is a trailingSlash option you can set to always so that routes/items/index.svelte corresponds to path /items/, but then routes/items/[id].svelte has path /items/[id]/ and we have the same problem again: one href value cannot work from both the index and the page of an individual item.
The only way I see right now is to use absolute path, but it's not very composable. My guess is that there is something I am doing wrong.
You're not missing anything - it's not currently possible in SvelteKit to have a trailing slash for some pages but not for others. There is an open GitHub issue you may be interested in that proposes adding additional trailingSlash options. This issue cites the exact problem you described:
The trailingSlash options introduced in #1404 don't make it straightforward to add trailing slashes to index pages but not to leaf pages. For example you might want to have /blog/ and /blog/some-post rather than /blog and /blog-some-post, since that allows the index page to contain relative links.
Until that feature is added, you'll need to use absolute paths.

Google Cloud Storage JSON REST API - Insert and List objects in a sub-directory in a bucket

I'm trying to figure out how to:
a) Store / insert an object on Google Cloud Storage within a sub-directory
b) List a given sub-directory's contents
I managed to resolve how to get an object here: Google Cloud Storage JSON REST API - Get object held in a sub-directory
However, the same logic doesn't seem to apply to these other types of call.
For store, this works:
https://www.googleapis.com/upload/storage/v1/b/bucket-name/o?uploadType=media&name=foldername%2objectname
but it then stores the file name on GCS as foldername_filename, which doesn't change functionality but isn't really ideal.
For listing objects in a bucket, not sure where the syntax for a nested directory should go in here: storage.googleapis.com/storage/v1/b/bucketname/o.
Any insight much appreciated.
The first thing to know is that GCS does not have directories or folders. It just has objects that share a fixed prefix. There are features that both gsutil and the UI used to create the illusion that folders do exist.
https://cloud.google.com/storage/docs/gsutil/addlhelp/HowSubdirectoriesWork
With that out of the way: to create an object with a prefix you need to URL encode the object name, as I recall %2F is the encoding for /:
https://cloud.google.com/storage/docs/request-endpoints#encoding
Finally to list only the objects with a common prefix you would use the prefix parameter:
https://cloud.google.com/storage/docs/json_api/v1/objects/list#parameters
Using prefix=foo/bar/baz (after encoding) would list all the objects in the foo/bar/baz "folder", note that this is recursive, it will include foo/bar/baz/quux/object-name in the results. To stop at one level you want to read about the delimiter parameter too.

CakePHP 3.x, How to get full path to a template file

I've tried $this->viewBuilder()->templatePath(), but this only returns the prefix and controller name. (ex. Dashboard/Users)
The full path is more like /usr/local/var/www/mysite/vendor/vendorname/users/src/Template/Dashboard/Users
I've tried a few other things like Plugin::path($this->viewBuilder()->plugin()) to get part of that path, but I have yet to find any piece of code that will return the settings for what the src folder is called and what the Template folder is called.
I could hard code them as 'src' . DS . 'Template', but was hoping I'd find something that would work even if those were changed through some config setting somewhere. (Ideally there would just be a viewBuilder->absoluteTemplatePath() or something like it.)
You can retrieve possible template paths via App::path().
If you want to retrieve the template path for your Users plugin, then you could do
$templatesPath = current(\Cake\Core\App::path('Template', 'Users'));
This would give you something like
/usr/local/var/www/mysite/vendor/vendorname/users/src/Template/
It should be noted that this method doesn't necessarily return only a single path, it does so for plugin templates though.
If you need the path to an actual file, then you'll have to concatenate the remaining path segments on your own.
See also
API > \Cake\Core\App::path()

Human readable file name

Whenever I create an ImageField using a file called moon.png, Django, correctly following my configuration settings, puts the file in:
campaign/primary-banner/2015/11/25/moon.png
or
campaign/primary-banner/2015/11/25/moon_RcJ3FuD.png
And that is the value of imagefield.name, which I can show to the user, but is not really user friendly.
I would like to show the name of ImageField.name, but in a human readable format. Is it possible to extract the original file name (moon.png) from the ImageField? The workarounds that I can think of are:
add an extra field to my model to hold the human readable file name. Extra work, which I would like to avoid: DRY.
process the imagefield.name value to extract the original filename, but this seems too complex (I would need to exactly understand how django is generating the filename in the first place, to make sure I cover corner cases)
I had similar problem and solved it by creating my own subdirectry under MEDIA_ROOT, in which I made directory structure involvind the date and also some unique identifier. Then I moved my file to that final subdirectory and put the name to FileField.name. Everything works like charm - files are unique (thanks to unique directories) and the final name is exactly what i want user to see (as there is no need to rename it - no conflict is possible)
p.filename=get_filename_of_existing_file_to_be_stored()
p.originalfilename=get_how_it_should_be_named()
masterobject=MyNewMaster.objects.get(pk=some_id)
uniq_name=masterobject.make_something_unique()
new_object=MyObject()
new_object.master=masterobject
new_object.some_fields=some_values
daystr=date.today().strftime('%y-%m-%d')
directory='MyDir/%s/%s/%s/'%(daystr,masterobject.id,uniq_name)
if not os.path.exists(os.path.join(settings.MEDIA_ROOT,directory)):
os.makedirs(os.path.join(settings.MEDIA_ROOT,directory))
fname=os.path.join(directory,p.originalfilename)
os.rename(p.filename,os.path.join(settings.MEDIA_ROOT,fname))
new_object.filename = fname
new_object.save()
Now everthing works for me and no conflicts are possible and even Django seems happy with this hack and provides the correct filename and url for everything i tried to do with MyObject :)
Now I ended with path like:
MyDir/2015-11-29/12345/child_7/moon.png

What does this URL mean?

http://localhost/students/index.cfm/register?action=studentreg
I did not understand the use of 'register' after index.cfm. Can anyone please help me understand what it could mean? There is a index.cfm file in students folder. Could register be a folder name?
They might be using special commands within their .htaccess files to modify the URL to point to something else.
Things like pointing home.html -> index.php?p=home
ColdFusion will execute index.cfm. It is up to the script to decide what to do with the /register that comes after.
This trick is used to build SEO friendly URL's. For example http://www.ohnuts.com/buy.cfm/bulk-nuts-seeds/almonds/roasted-salted - buy.com uses the /bulk-nuts-seeds/almonds/roasted-salted to determine which page to show.
Whats nice about this is it avoids custom 404 error handlers and URL rewrites. This makes it easier for your application to directly manage the URL's used.
I don't know if it works on all platforms, as I've only used it on IIS.
You want to look into the cgi.PATH_INFO variable, it is populated automatically by CF server when such URL format used.
Better real-life example would look something like this.
I have an URL which I want to make prettier:
http://mybikesite/index.cfm?category=bicycles&manufacturer=cannondale&model=trail-sl-4
I can rewrite it this way:
http://mybikesite/index.cfm/category/bicycles/manufacturer/cannondale/model/trail-sl-4
Our cgi.PATH_INFO value is: /category/bicycles/manufacturer/cannondale/model/trail-sl-4
We can parse it using list functions to get the same data as original URL gives us automatically.
Second part of your URL is plain GET variable, it is pushed into URL scope as usually.
Both formats can be mixed, GET vars may be used for paging or any other secondary stuff.
index.cfm is using either a CFIF IsDefind("register") or a CFIF #cgi.Path_Info# CONTAINS statements to execute a function or perform a logic step.