Giter Site home page Giter Site logo

download-manager's Introduction

Download Manager

Python program that manages Downloads

This is a Python program which manages a users Downloads easily.

Have you ever downloaded a bunch of files and have to copy and paste them into the desired foler? (ex lecture notes which need to be moved from Downloads into Desktop/LectureNotes).

In Mac you are not allowed to Cut and paste the folders, so the user has to copy, paste, and the move to trash, which is a process. Additionaly, if you want to rename your file, you have to go one by one and rename each file.

Luckily the os library in Python allows for direct access to files and folders, so i tried to make this process easier by creating this program. Below i will explain each function and main lines of code which do this task.

Function 1: main()


Gets the user input for which directory they want to move the downloads folder to. Ex: if you want to move the contents from the Downloads folder into a folder in the Desktop.

Input Prompt

move_dir = str(input("Enter main directory to move Download File (ex: Desktop): "))
cwd = os.path.expanduser("~/Downloads/")
move_dir = move_dir[0].upper() + move_dir[1:]
mvdir = os.path.expanduser("~/"+move_dir+"/")

Output

  • move_dir: A variable that holds the directory where the Download file must go.
  • cwd (current working directory): Stores the path of the Download directory, this is fixed as we are moving files from Downloads to external directories.

How do we get this path?

cwd = os.path.expanduser("~/Downloads/")
  • os.path.expanduser method in Python is used to expand an initial path component ~( tilde symbol) or ~user in the given path to user’s home directory. From Geeks for Geeks.

So cwd becomes:

cwd = '/Users/[username]/Downloads/'

This is important to understand as in the next line we concatenate move_dir into the os.path.expanduser so the user can choose a custom directory, rather than being restricted to one, like Documents.

mvdir = os.path.expanduser("~/"+move_dir+"/")

Quick: If you are wondering what this line does:

move_dir = move_dir[0].upper() + move_dir[1:]

It allows the user to enter either "Documents" or "documents" as the os.path.expanduser will only allow for the directory name with caps.


Gets the user input for which folder they want to move the Downloads file into.

folder_name = str(input("Enter folder name: "))
print("If folder exists, file will be moved, if not new folder will be crated")

mvdir += folder_name

if not os.path.exists(mvdir):
    os.makedirs(mvdir)

folder_name is concatenated with mvdir to specify the folder in the Directory to move the Download file into.

The if statement:

if not os.path.exists(mvdir):

Checks is the path exists, if not it uses the os function os.makedirs(mvdir) and creates a new folder in the directory with the name folder_name

os.makedir vs os.makedirs:

  • os.makedir(path): Creates folder in current working directory names path

  • os.makedirs(path): Similar to makedir, but makes all intermediate-level directories needed to contain the leaf directory.

Information from docs.python

Call a function to initialize the Downloads directory files, and calls another function to move the files

current = initialize_folder(cwd)
del current[0]

print(' ')
print("Files to be moved must be most recently downloaded files")
num_files = int(input("Enter how many downloaded files to move: "))
print("****************************************************")
print(" ")

move_file(current, num_files, cwd, mvdir)

print(" ")
print("****************************************************")

The line:

current = initialize_folder(cwd)

Calls the function initialize_folder and assigns its return value into current.

What this function does will be explained in detail later, but for now we can think of it as a function that returns a list of sorted dictionaries (by timne) that contain each file in Downloads name, and a time. The time is how recently the file was modified, i.e how recently it was downloaded.

Note: del current[0] deletes the first element of the list of dictionaries. This is done beacuse the first item is ".DS_Store" which is a hidden file, however, it still shows up in the list and is always the first item. So we delete it from our list.

The line:

move_file(current, num_files, cwd, mvdir)

What this function does will be explained in detail later, but for now we can think of it as a function that moves the files into the desired folder.

Function 2: initialize_folder(cwd)


Move all files in Downoalds into a dictionary

os.chdir(cwd)

time_dict = {}
for f in os.listdir(cwd):
    time_dict.update({f:os.stat(f).st_mtime})

The parameter passed to initialize_folder is cwd, which is the current working directory, or: "~/Downloads" in Mac.

  • os.chdir: This changes the current working directory into the file name passed into it, in this case cwd, which is the Downloads directory.

  • time_dict = {} - initializes a empy dictionary to be populated

Loop throgh each file in Downloads:

for f in os.listdir(cwd):
    time_dict.update({f:os.stat(f).st_mtime})
  • os.listdir(cwd) returns a list of all the files in Downloads.

Next we update the dictionary with f (the current file), and the last modified time.

  • The last modified time is got by the function os.stat(f).st_mtime. os.stat(f) returns many statistics about the file, all of these can be seen here: Tutorialspoint - os.stat.

we want the most recent modification time so we specify this by adding .st_mtime.

Return the sorted list of dictionaries

Now we have a list populated by the a dictionary filename and most recent modification time, however, the way the files are iterated through in the Downloads folder depends on how they are stored in the OS. They are not sorted by most recent modification time, so we have to return a sorted dictionary list.

return(sorted(time_dict.items(), key=lambda item: item[1],reverse=True))

The built in function in Python sorted() returns a sorted list. It uses a sorting algorithm called TimeSort, which was bult specifically for Python. It has a worst case runtime of around O(nlog(n)) which is quite efficient. More information at Wikipedia.

Function 3: move_file(current, num_files, cwd, mvdir)


Move the files and ask the user if they want to change the file name

i = 0
for file in current:
    i += 1
    if i > num_files:
        break

This is the loop part which loops through the first i elements of the dictionary which is stored in current. The code exits the loop when i > num_files which is when it looped through the first num_files elements in the list.

curr_file = file[0]
print(' ')

print("File ",i,": ",curr_file)

rename = str(input("Rename this file? (Enter Yes or No): "))
rename = rename[0].upper() + rename[1:]

if rename == 'Yes':
    print(' ')
    new_name = str(input("Enter new name (include extention): "))
    os.rename(curr_file,new_name)
    print('Moving ',new_name,'...')
    shutil.move(os.path.join(cwd,new_name),mvdir)
else:
    print('Moving ',curr_file,'...')
    shutil.move(os.path.join(cwd,curr_file),mvdir)

This part is where we rename and actually move the file. We set curr_file to be file[0] to access the file name, and next ask the user for the desired file name. If the user says 'Yes' we we get the name and use os.rename() to rename the file.

  • Python method rename(src,dst) renames the file or directory src to dst. If dst is a file or directory (already present), OSError will be raised. From Tutorialspoint.

After renaming the file, we move the file using the function shutil.move().

  • shutil.move() method Recursively moves a file or directory (source) to another location (destination) and returns the destination. From Geeks for Geeks.

Inside the move function you might have noticed a join function, this joins the new name to current working directory so when we move it it will move the exact file. You might be thinking, why do we have to use a join function? cant we just concatenate the two strings?

There is a good StackOverflow answer which addresses this.

  • os.path.join() method in Python join one or more path components intelligently. This method concatenates various path components with exactly one directory separator (‘/’) following each non-empty part except the last path component. If the last path component to be joined is empty then a directory seperator (‘/’) is put at the end. From Geeks for Geeks.

download-manager's People

Contributors

sharithg avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.