Upload files to 'studio'
This commit is contained in:
parent
9af4596da0
commit
18dfef6f17
2 changed files with 407 additions and 0 deletions
244
studio/analytics.py
Normal file
244
studio/analytics.py
Normal file
|
@ -0,0 +1,244 @@
|
|||
# THIS FILE IS A PART OF VCStudio
|
||||
# PYTHON 3
|
||||
|
||||
import os
|
||||
import datetime
|
||||
|
||||
#from studio import checklist
|
||||
import checklist
|
||||
|
||||
def get_legacy(project_location):
|
||||
|
||||
# This function will return analytics data about a project. This particular
|
||||
# function is desinged to read old, Blender-Organizer projects. It's a first
|
||||
# step of conversion. And used to display basic analitycs into the
|
||||
# project-manager.
|
||||
|
||||
data = {
|
||||
"name" : "", # Name of the project (typed properly)
|
||||
"director" : "", # Name of the project's director.
|
||||
"status" : "", # Projects's comment / type
|
||||
"donework" : 0.0, # Percentage of Assets and Scenes done
|
||||
"fraction" : 0.0, # Project's completion percentage
|
||||
"checklist" : 0.0, # Project's main checklist percentage
|
||||
"startdate" : "0000/00/00", # Date of the start of the project
|
||||
"deadline" : "0000/00/00", # Date when project's deadline is
|
||||
"duration" : 0, # Amount in days between startdate and deadline
|
||||
"timepassed" : 0.0, # Percentage of how much time had passed
|
||||
"dayspassed" : 0, # Amount of days since the startdate
|
||||
"chr_factor" : 1, # Importance factor for Characters
|
||||
"veh_factor" : 1, # Importance factor for Vehicles
|
||||
"loc_factor" : 1, # Importance factor for Locations
|
||||
"obj_factor" : 1, # Importance factor for Objects (Other)
|
||||
"rnd_factor" : 1, # Importance factor for Scenes (Renders)
|
||||
"chr" : 0.0, # Percentage of Characters done
|
||||
"veh" : 0.0, # Percentage of Vehicles done
|
||||
"loc" : 0.0, # Percentage of Locations done
|
||||
"obj" : 0.0, # Percentage of Objects (Other) done
|
||||
"rnd" : 0.0, # Percentage of Scenes (Renders) done
|
||||
"dates" : {} # Per date, detailed data about the project
|
||||
}
|
||||
|
||||
# Okay let's get the name, director and status from the old file. Funny that
|
||||
# it still survived from so far back. In the Organizer 1.0 you had to manually
|
||||
# type in the number of assets that had to be done in each category.
|
||||
|
||||
# And so for this task was created a file called "project.data". Here is
|
||||
# an example :
|
||||
|
||||
# Project :Moria's Race
|
||||
# Status :Short Action Driving Film
|
||||
# Director :J.Y.Amihud
|
||||
# Character:1
|
||||
# Locations:1
|
||||
# Objects :1
|
||||
# Vehicles :1
|
||||
# Scenes :4
|
||||
|
||||
# So that's survived up to the last Blender-Organizer. But no longer the
|
||||
# last 5 lines were utilized. I was using it mainly for the first 3 things.
|
||||
|
||||
# Tho from a version 4.85 of Blender-Organizer those last lines were used
|
||||
# to controll the influence factor. Basically the number stored will multiply
|
||||
# the number of times a given category is counted in the final percentage.
|
||||
|
||||
# For example animating scenes should take more then half the time of the
|
||||
# project. More then 50% of the project then should be in the scenes. But
|
||||
# previous / primitive algorythm was giving each category an even 20%. So
|
||||
# of course I fixed it. LOL.
|
||||
|
||||
# I think for VCStudio I gonna make a more unified file format. That will
|
||||
# unite all "project.data", "percentage_hystory.data", "history.data" and
|
||||
# "schedule.data".
|
||||
|
||||
# I'm going to still have the main checklist separate tho. The checklist
|
||||
# format is quite good.
|
||||
|
||||
projectdata = open(project_location+"/project.data")
|
||||
projectdata = projectdata.read()
|
||||
projectdata = projectdata.split("\n")
|
||||
|
||||
for line in projectdata:
|
||||
|
||||
if line.startswith("Project"):
|
||||
data["name"] = line[line.find(":")+1:]
|
||||
|
||||
elif line.startswith("Status"):
|
||||
data["status"] = line[line.find(":")+1:]
|
||||
|
||||
elif line.startswith("Director"):
|
||||
data["director"] = line[line.find(":")+1:]
|
||||
|
||||
# Next up some integer conversions. So...
|
||||
|
||||
elif line.startswith("Character"):
|
||||
try:
|
||||
data["chr_factor"] = int(line[line.find(":")+1:])
|
||||
except:
|
||||
data["chr_factor"] = 1
|
||||
|
||||
|
||||
elif line.startswith("Vehicles"):
|
||||
try:
|
||||
data["veh_factor"] = int(line[line.find(":")+1:])
|
||||
except:
|
||||
data["veh_factor"] = 1
|
||||
|
||||
elif line.startswith("Locations"):
|
||||
try:
|
||||
data["loc_factor"] = int(line[line.find(":")+1:])
|
||||
except:
|
||||
data["loc_factor"] = 1
|
||||
|
||||
elif line.startswith("Objects"):
|
||||
try:
|
||||
data["obj_factor"] = int(line[line.find(":")+1:])
|
||||
except:
|
||||
data["obj_factor"] = 1
|
||||
|
||||
elif line.startswith("Scenes"):
|
||||
try:
|
||||
data["rnd_factor"] = int(line[line.find(":")+1:])
|
||||
except:
|
||||
data["rnd_factor"] = 1
|
||||
|
||||
# Okay this first file was easy. Let's now parse the main checklist and
|
||||
# get 5 more values. Funny thing is that for the old checklists and new
|
||||
# checklists you can use the same function to read them. ( The main check-
|
||||
# list data ). But old checklists had something else in there that was
|
||||
# making them a bit different from VCStudio checklists. It's the STR and FIN
|
||||
# variables in the beginig.
|
||||
|
||||
# See in the Organizer 1.0 there was no scheduling system as there was in
|
||||
# Blender-Orgaznier 4.9. The scheduling was done per asset and not per
|
||||
# action in the checklist. So STR and FIN were 2 dates between which you
|
||||
# should have had working on the asset.
|
||||
|
||||
# But in the main checklists ("project.progress") those 2 survived to the
|
||||
# late Blender-Organizer as a project startdate and deadline.
|
||||
|
||||
# One more rub that I have is that date format was 00/00/0000 and not the
|
||||
# way better one 0000/00/00 which makes sorting easy. So yeah...
|
||||
|
||||
old_date_format = "%d/%m/%Y"
|
||||
new_date_format = "%Y/%m/%d"
|
||||
|
||||
projectdata = open(project_location+"/project.progress")
|
||||
projectdata = projectdata.read()
|
||||
projectdata = projectdata.split("\n")
|
||||
|
||||
startdate = datetime.datetime.today()
|
||||
deadline = datetime.datetime.today()
|
||||
|
||||
for line in projectdata:
|
||||
if line.startswith("STR"):
|
||||
startdate = datetime.datetime.strptime(line[4:], old_date_format)
|
||||
data["startdate"] = datetime.datetime.strftime(startdate, new_date_format)
|
||||
|
||||
elif line.startswith("FIN"):
|
||||
deadline = datetime.datetime.strptime(line[4:], old_date_format)
|
||||
data["deadline"] = datetime.datetime.strftime(deadline, new_date_format)
|
||||
|
||||
# So we've go the dates. Let's calculate time perventage I guess.
|
||||
delta = deadline - startdate
|
||||
data["duration"] = int(delta.days)
|
||||
|
||||
delta = datetime.datetime.today() - startdate
|
||||
data["dayspassed"] = int(delta.days)
|
||||
|
||||
data["timepassed"] = data["dayspassed"] / data["duration"]
|
||||
if data["timepassed"] > 1.0:
|
||||
data["timepassed"] = 1.0
|
||||
|
||||
# Now let's lauch the main checklist and get the data from there. I mean
|
||||
# the percentage. Btw It's just a hard thing. That I needed a separate
|
||||
# function for it.
|
||||
|
||||
projectdata = checklist.get_list(project_location+"/project.progress")
|
||||
data["checklist"] = projectdata["fraction"]
|
||||
|
||||
# NEXT THING. As I love to type it into place where people read me while I'm
|
||||
# working. We've got data from 2 files. Now we need to get data from ALL the
|
||||
# project.
|
||||
|
||||
# First we going to get data about the assets. Because it's relativelly easy
|
||||
# compared to the story. For which you need to parce a crazy complicated .bos
|
||||
# file. Which is a complex database in it's own right.
|
||||
|
||||
# So let's go and quickly get data about the assets.
|
||||
|
||||
asstfols = ["chr", "veh", "loc", "obj"]
|
||||
astlist = []
|
||||
|
||||
for n , f in enumerate(asstfols):
|
||||
|
||||
flist = []
|
||||
|
||||
if len(os.listdir(project_location+"/dev/"+f)) > 0:
|
||||
for asset in os.listdir(project_location+"/dev/"+f):
|
||||
|
||||
if asset+".blend" in os.listdir(project_location+"/ast/"+f):
|
||||
flist.append(1.0)
|
||||
|
||||
else:
|
||||
try:
|
||||
fcheck = checklist.get_list(project_location+"/dev/"+f+"/"+asset+"/asset.progress")
|
||||
flist.append(fcheck["fraction"])
|
||||
except:
|
||||
flist.append(0.0)
|
||||
|
||||
# The multiplication thing that I was talking about earlier.
|
||||
|
||||
multiply = data[f+"_factor"]
|
||||
for m in range(multiply):
|
||||
astlist.append(sum(flist)/len(flist))
|
||||
|
||||
data[f] = sum(flist)/len(flist)
|
||||
|
||||
|
||||
# For the next step I need to have the story parsed and read. But it's going
|
||||
# to be so hard. That I will need to write a separate function for it.
|
||||
|
||||
data["rnd"] = 0.0
|
||||
|
||||
# After all of it we need to get the final project percentage.
|
||||
multiply = data["rnd_factor"]
|
||||
for m in range(multiply):
|
||||
astlist.append(data["rnd"])
|
||||
|
||||
try:
|
||||
data["donework"] = sum(astlist) / len(astlist)
|
||||
except:
|
||||
data["donework"] = 0.0
|
||||
data["fraction"] = (data["donework"] + data["checklist"]) / 2
|
||||
|
||||
# Next section of this data gathering will be about history, scheduling and
|
||||
# similar things. I gonna create a dictionary of dates. And input data about
|
||||
# those dates into the dates.
|
||||
|
||||
|
||||
return data
|
||||
|
||||
this = get_legacy("/home/vcs/Projects/Films/Shorts/MoriasRace")
|
||||
for i in this:
|
||||
print(i, " : " ,this[i])
|
163
studio/checklist.py
Normal file
163
studio/checklist.py
Normal file
|
@ -0,0 +1,163 @@
|
|||
# THIS FILE IS A PART OF VCStudio
|
||||
# PYTHON 3
|
||||
|
||||
import os
|
||||
|
||||
def get_list(filepath):
|
||||
|
||||
# This fucntion converts text documents. (.progress) into a more machine
|
||||
# friendly recursive dict.
|
||||
|
||||
# In the original organizer evaluation of the checklist was done separatelly
|
||||
# in a different function. Which made it very messy for recursive stuff.
|
||||
# I will attemp to combine it. And make it more clean as a result.
|
||||
|
||||
checklist = {
|
||||
"fraction":0.0, # The percentage of a checklist. From 0.0 to 1.0
|
||||
"string":filepath,
|
||||
"editing":False,# Whethere the string is during editing. UI.
|
||||
"open":True, # Whether to draw the suptasks. UI.
|
||||
"subtasks":[] # List of subtastks. (In the same format as the checklist)
|
||||
}
|
||||
|
||||
data = open(filepath)
|
||||
data = data.read()
|
||||
data = data.split("\n")
|
||||
|
||||
# Let's filter out all the comments. Lines starting with #. For some reason
|
||||
# in the old organizer. I just thought it wasn't important. LOL. And just
|
||||
# started reading from the 10th line.
|
||||
|
||||
# Here is an example of the first 9 lines.
|
||||
|
||||
# 1 #### Blender orgainizer checklist format
|
||||
# 2 #### INDINTATION (4 SPACES LONG)
|
||||
# 3 #### STR means Start date of the ASSET
|
||||
# 4 #### FIN means Finish deadline of the asset
|
||||
# 5 #### [ ] means that task is on list
|
||||
# 6 #### [V] means that tast is finished
|
||||
# 7 #### DO NOT USE EMPTY LINES
|
||||
# 8 STR 24/02/2020
|
||||
# 9 FIN 01/05/2021
|
||||
|
||||
# You can see a trace from a very long time ago. From the first versions
|
||||
# of the blender organizer. The STR and FIN values. Which are start and
|
||||
# deadline of the project.
|
||||
|
||||
# I guess we need to filter it out a bit differently. Checking whether a
|
||||
# given line starts with a [ or with a number of spaces and [. This will
|
||||
# make the file a little more open to editing by hand. Without too much
|
||||
# worrying that something will break.
|
||||
|
||||
cleandata = []
|
||||
|
||||
for line in data:
|
||||
|
||||
# So not to mangle the line.
|
||||
tmp = line
|
||||
while tmp.startswith(" "):
|
||||
tmp = tmp[1:]
|
||||
|
||||
# Checking
|
||||
if tmp.startswith("[ ]") or tmp.startswith("[V]"):
|
||||
cleandata.append(line)
|
||||
|
||||
# Now since we have the cleandata. We can try to parse it somehow into a
|
||||
# checklist thing. For this we need a reqursion. I gonna use a method from
|
||||
# the blender-organizer. By running the function with in itself. It's not
|
||||
# very wise. I know. In python3 it will give you no more then 996 recursions
|
||||
# untill it will declare an error. BUT. It's 996 layers of a subtaks.
|
||||
# For now I don't see a need in so many subtasks. Let's think of layers of
|
||||
# subtasks as of memory. This laptop has only 8 GB of RAM. I can't put more
|
||||
# data into it even if I wanted.
|
||||
|
||||
def convert(part, indent=0):
|
||||
# If a thing have subtasks it should not even be a checkbox. So trying
|
||||
# To evaluate it's fraction by whether it's a [ ] or [V] shoun't be
|
||||
# done.
|
||||
|
||||
subtask = []
|
||||
|
||||
for num, line in enumerate(part):
|
||||
|
||||
# Let's get the NEXT line. I'm not kidding. We gonna work with the
|
||||
# next line to see whether to count this lines [V]
|
||||
|
||||
|
||||
if line[indent:].startswith("["):
|
||||
|
||||
thisline = {
|
||||
"fraction":0.0,
|
||||
"string":line[line.find("]")+2:],
|
||||
"editing":False,
|
||||
"open":False,
|
||||
"subtasks":[]
|
||||
}
|
||||
|
||||
try:
|
||||
nextline = part[num+1]
|
||||
except:
|
||||
nextline = ""
|
||||
|
||||
if not line[line.find("]")+1] == ".":
|
||||
thisline["open"] = True
|
||||
|
||||
if nextline.find("[")-1 <= indent:
|
||||
if line[indent:].startswith("[V]"):
|
||||
thisline["fraction"] = 1.0
|
||||
|
||||
else:
|
||||
subpart = []
|
||||
subdent = indent
|
||||
for n, l in enumerate(part[num+1:]):
|
||||
if n == 0:
|
||||
subdent = l.find("[")
|
||||
|
||||
if l.find("[")-1 <= indent:
|
||||
break
|
||||
|
||||
else:
|
||||
subpart.append(l)
|
||||
|
||||
#print(subpart)
|
||||
thisline["subtasks"] = convert(subpart, subdent)
|
||||
|
||||
fracs = []
|
||||
for task in thisline["subtasks"]:
|
||||
if not task["string"].startswith("#"):
|
||||
fracs.append(task["fraction"])
|
||||
|
||||
try:
|
||||
thisline["fraction"] = sum(fracs) / len(fracs)
|
||||
except:
|
||||
thisline["fraction"] = 0.0
|
||||
|
||||
# Sometime it was showing 99% when infect it's 100%
|
||||
if thisline["fraction"] == 0.9999:
|
||||
thisline["fraction"] = 1.0
|
||||
|
||||
|
||||
subtask.append(thisline)
|
||||
|
||||
return subtask
|
||||
|
||||
|
||||
checklist["subtasks"] = convert(cleandata)
|
||||
fracs = []
|
||||
for task in checklist["subtasks"]:
|
||||
if not task["string"].startswith("#"):
|
||||
fracs.append(task["fraction"])
|
||||
|
||||
try:
|
||||
checklist["fraction"] = sum(fracs) / len(fracs)
|
||||
except:
|
||||
checklist["fraction"] = 0.0
|
||||
|
||||
# Sometime it was showing 99% when infect it's 100%
|
||||
if checklist["fraction"] == 0.9999:
|
||||
checklist["fraction"] = 1.0
|
||||
|
||||
|
||||
return checklist
|
||||
|
||||
|
Loading…
Add table
Reference in a new issue