History / Scheduling Parsing
Now it can read and even save files from the history / scheduling form the old Blender-Organizer. In the end you can see some commented file writing things. You can plug your own location there and test this feature out. It gives hell of a clean file. I know I'll have to be able to parse the new file as well. Yeah.
This commit is contained in:
parent
dcab48d9b9
commit
e85be921de
1 changed files with 460 additions and 0 deletions
|
@ -238,6 +238,466 @@ def get_legacy(project_location):
|
|||
# similar things. I gonna create a dictionary of dates. And input data about
|
||||
# those dates into the dates.
|
||||
|
||||
# One thing that I have to make sure about is that some dates could be out-
|
||||
# side of the range between startdate and deadline. So I have to read the
|
||||
# files and add them dynamically.
|
||||
|
||||
# Let's start by reading scheduling.
|
||||
|
||||
sdata = open(project_location+"/schedule.data")
|
||||
sdata = sdata.read()
|
||||
sdata = sdata.split("\n")
|
||||
|
||||
# Good that schedules already have the right date format. Altho I think of
|
||||
# actually using a datetime object as a date. Or is it too much? Let me think
|
||||
# I do think loudly. And sinse I have nobody to talk to I will type it here.
|
||||
# If you couldn't tell already. Let's write it as a string for now. Because
|
||||
# it's easier to work wit strings. Maybe in future I will write it as a
|
||||
# datetime object. If i'll find benefit to this.
|
||||
|
||||
for date in sdata:
|
||||
|
||||
# Let's separate the string into 3 components. Basically scheduling is
|
||||
# list of tasks in various checklists through out the project. Example:
|
||||
|
||||
# 2020/11/30 /dev/obj/Morias_Bike/asset.progress Rigging=:> Make Bones
|
||||
# 2021/05/01 project.progress Marketing=:> Release
|
||||
|
||||
# The first entry is a date formatted yyyy/mm/dd. Then comes path of the
|
||||
# checklist location. Relative to the project_location. Then a url type
|
||||
# thing for with in the checklist. Separating entries with "=:>"
|
||||
|
||||
# Also I have to note that in the old Blender-Organizer date 1997/07/30
|
||||
# which is my birthday, will make the task be everyday. It will have it's
|
||||
# own Green color. Usually when you make a new project there are a list
|
||||
# of task created for this date.
|
||||
|
||||
if date:
|
||||
d = date[:date.find(" ")] # Date
|
||||
f = date[date.find(" ")+1:date.replace(" ", ".", 1).find(" ")] # File
|
||||
t = date[date.replace(" ", ".", 1).find(" ")+1:].split("=:>") # Task
|
||||
|
||||
if d not in data["dates"]:
|
||||
data["dates"][d] = {}
|
||||
|
||||
# Now in order to decide how to input this data into the data["dates"]
|
||||
# we need to look at history at first. Because first of all it has
|
||||
# similar syntax. But on the other hand it's a bit more complex.
|
||||
|
||||
# 2020/07/05 03:06:34 /dev/chr/Civilian_Child_2/asset.progress Rigging=:> Face Rig=:> Mouth area [V]
|
||||
# 2020/07/05 03:06:35 /dev/chr/Civilian_Child_2/asset.progress Rigging=:> Ready to make AST [V]
|
||||
# 2020/07/05 03:06:37 /dev/chr/Civilian_Child_2/Civilian_Child_2.blend [Openned]
|
||||
# 2020/07/05 03:07:56 /dev/chr/Civilian_Child_2/autolink.data [Updated]
|
||||
# 2020/07/05 03:08:08 pln/main.bos [Edited]
|
||||
# 2020/07/05 03:08:13 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Openned]
|
||||
# 2020/07/05 03:08:25 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Linked]
|
||||
# 2020/07/05 03:08:25 /rnd/Scene_2a5jfq6126fe/1/Cc1_IK_Test.blend [Openned]
|
||||
|
||||
# Also history has a feature missing in the schedules. But there is
|
||||
# a rub. Scheduling you can rearange by moving them arround. And you
|
||||
# can simply move a task to a different day if you so desire.
|
||||
|
||||
# In the history apart from the date you also have time up to the second
|
||||
# which is a bit more precise in terms of when exactly you made a
|
||||
# given task. And I would like scheduling to have the same type of
|
||||
# precision. Maybe even introduce a notification system if a certain
|
||||
# task is due. But it makes the moving of tasks highly complicated
|
||||
# to visualize.
|
||||
|
||||
# Maybe a timeline could be a cool idea. Like in the VSE of blender.
|
||||
# a place where you could put specific points on a timeline. And time
|
||||
# to the next point will be hte length of the part.
|
||||
|
||||
# You could move the dots so to change timing of parts. And maybe
|
||||
# select them to type in precise values. Could work.
|
||||
|
||||
|
||||
# Let's separate the schedule to 3 types. Asset, Scene, Main.
|
||||
|
||||
# If it's a scene we are talking about. IK it's a bit shitty. Because
|
||||
# I will need to parse this as well. But who cares.
|
||||
|
||||
if f.startswith("/rnd"):
|
||||
ty = "scenes"
|
||||
url = f[:f.rfind("/")].replace("/rnd", "", 1)
|
||||
url = url[:url.rfind("/")]
|
||||
fn = f.replace("/rnd", "", 1).replace(url, "")
|
||||
|
||||
|
||||
|
||||
|
||||
elif f.startswith("/dev"):
|
||||
ty = "assets"
|
||||
url = f[:f.rfind("/")].replace("/dev", "", 1)
|
||||
fn = f.replace("/dev", "", 1).replace(url, "")
|
||||
|
||||
|
||||
|
||||
else:
|
||||
ty = "files"
|
||||
url = ""
|
||||
fn = f
|
||||
|
||||
if not ty in data["dates"][d]:
|
||||
data["dates"][d][ty] = {}
|
||||
|
||||
if not url in data["dates"][d][ty]:
|
||||
data["dates"][d][ty][url] = []
|
||||
|
||||
data["dates"][d][ty][url].append([
|
||||
"00:00:00",
|
||||
"schedule",
|
||||
fn,
|
||||
t
|
||||
])
|
||||
|
||||
# Okay I don't really know what exactly did I just do. But it's seems like
|
||||
# a good starting point. Up to a working verion of VCStudio i can edit and
|
||||
# change these all I want. Okay I guess it's time to parse another, way
|
||||
# harder file. The history. LOL.
|
||||
|
||||
# First let's deal with the persantage history file. It's kind of a funny
|
||||
# one as well. The funny part is that it has no consistancy at all. I will
|
||||
# need to convert it as well. It has a stupid %y-%m-%d format. Which is WTF.
|
||||
|
||||
history_percentage_format = "%y-%m-%d"
|
||||
|
||||
hdata = open(project_location+"/percentage_hystory.data") # IK spelling LOL
|
||||
hdata = hdata.read()
|
||||
hdata = hdata.split("\n")
|
||||
|
||||
for date in hdata:
|
||||
if date.startswith("DATE"):
|
||||
|
||||
# An example of the formatting is actually quite amazing. It's going
|
||||
# to be realively simple. Example:
|
||||
|
||||
# DATE 20-06-26 42.64%
|
||||
|
||||
# As you can see it's the word DATE then that date then the fraction
|
||||
# as a percantage. Separated by a spacebar.
|
||||
|
||||
try:
|
||||
t, d, f = date.split(" ")
|
||||
|
||||
# Converting the d into a normal date
|
||||
|
||||
d = datetime.datetime.strptime(d, history_percentage_format)
|
||||
d = datetime.datetime.strftime(d, new_date_format)
|
||||
|
||||
# Converting the f into a fraction
|
||||
|
||||
f = float(f.replace("%", "")) / 100
|
||||
|
||||
except:
|
||||
continue
|
||||
|
||||
# I just don't want to deal with poeple who are editing the file
|
||||
# manually and then say I did something wrong that the program crashed
|
||||
|
||||
if d not in data["dates"]:
|
||||
data["dates"][d] = {}
|
||||
|
||||
data["dates"][d]["fractions"] = {
|
||||
"project":f, # The fraction we recieved from the file
|
||||
"checklist":0.0, # Place holder for checklist fraction
|
||||
"chr":0.0, # \
|
||||
"veh":0.0, # |
|
||||
"loc":0.0, # > - Plaseholders for categories
|
||||
"obj":0.0, # |
|
||||
"rnd":0.0 # /
|
||||
}
|
||||
|
||||
|
||||
# Okay this file was parsed. Which was relativelly simple. NOW. Let's
|
||||
# do something a bit harder. Or is it as simple as the other? IDK
|
||||
# History file. Example was a bit earlier.
|
||||
|
||||
hdata = open(project_location+"/history.data")
|
||||
hdata = hdata.read()
|
||||
hdata = hdata.split("\n")
|
||||
|
||||
for line in hdata:
|
||||
|
||||
if not line:
|
||||
continue
|
||||
|
||||
# So basically every line is quite simple from the left side. But becomes
|
||||
# quite complex on the right side. So let's get the left side things
|
||||
|
||||
date = line[:line.find(" ")]
|
||||
time = line[line.find(" ")+1:line.replace(" ", ".", 1).find(" ")]
|
||||
path = line[line.replace(" ", ".", 1).find(" ")+1:line.replace(" ", ".", 2).find(" ")]
|
||||
done = line[line.replace(" ", ".", 2).find(" ")+1:]
|
||||
|
||||
# I made a mistake allowing paths to have spaces in them. And I need to
|
||||
# make sure we have the whole path and not only up to a point.
|
||||
|
||||
while done[0] != "[" and ".progress" not in path and "[" in done:
|
||||
|
||||
transporting = done[:done.find(" ")]
|
||||
|
||||
path = path+" "+transporting
|
||||
done = done.replace(transporting+" ", "")
|
||||
|
||||
|
||||
# "date" will be our standard date. yyyy/mm/dd. Then "time" is out time
|
||||
# from the current day. 24 hours system. hh:mm:ss. "path" is the file to
|
||||
# which the change was done. We will need to parse this one. Because it
|
||||
# contains the full path to let's say a blend file. While we want to
|
||||
# know which asset for example was accessed. Then "done" is the rest of
|
||||
# the string. Basically it tells what was actually done with a given file.
|
||||
# We will need to parse this one as well somehow. And it scares me a lot
|
||||
|
||||
# One thing that we can use it for is restoring the old scheduling list.
|
||||
# Becuase in lazy attempt to make user know that a given task is finished
|
||||
# I would just delete the task from the schedule file entirely. But
|
||||
# in the history file you can find instances of [scheduled] with the full
|
||||
# path of a task and the date to which it was scheduled. So yeah.
|
||||
|
||||
# Let's get to work.
|
||||
|
||||
f = path # Copied from previous
|
||||
|
||||
if f.startswith("/rnd"):
|
||||
ty = "scenes"
|
||||
url = f[:f.rfind("/")].replace("/rnd", "", 1)
|
||||
url = url[:url.rfind("/")]
|
||||
fn = f.replace("/rnd", "", 1).replace(url, "")
|
||||
|
||||
|
||||
elif f.startswith("/dev"):
|
||||
ty = "assets"
|
||||
url = f[:f.rfind("/")].replace("/dev", "", 1)
|
||||
fn = f.replace("/dev", "", 1).replace(url, "")
|
||||
|
||||
elif f.startswith("/ast") and ".blend" in f:
|
||||
ty = "assets"
|
||||
url = f[:f.rfind(".")].replace("/ast", "", 1)
|
||||
fn = "[asset_blend]"
|
||||
|
||||
else:
|
||||
ty = "files"
|
||||
url = ""
|
||||
fn = f
|
||||
|
||||
# Now in order to parse the "done" variable. We need to define functions
|
||||
# that we are not looking for. Simple (Trivial) Operations.
|
||||
|
||||
simple_operations = [
|
||||
"[Edited]",
|
||||
"[Openned]",
|
||||
"[Linked]",
|
||||
"[Edited]",
|
||||
"[Updated]",
|
||||
"[Added]",
|
||||
"[Added Asset]"
|
||||
]
|
||||
|
||||
# Basically if "done" in on that list. It's something to do with
|
||||
# checklists. And then we have either [V], [ ] or [Scheduled]
|
||||
|
||||
if done not in simple_operations:
|
||||
if "[Scheduled]" in done:
|
||||
|
||||
# These are the missing scheduling data I was talking about.
|
||||
# Let's parse this data from the back. The one on the back
|
||||
# should be the DATE. Then spacebar. Then the [Scheduled] then
|
||||
# another spacebar then the task.
|
||||
|
||||
missingdate = done[done.rfind(" ")+1:]
|
||||
missingtask = done[:done.rfind(" [Scheduled]")].split("=:>")
|
||||
|
||||
# Let's add them into the data. I don't what it will be. Let's
|
||||
# see.
|
||||
|
||||
|
||||
if not missingdate in data["dates"]:
|
||||
data["dates"][missingdate] = {}
|
||||
|
||||
if not ty in data["dates"][missingdate]:
|
||||
data["dates"][missingdate][ty] = {}
|
||||
|
||||
if not url in data["dates"][missingdate][ty]:
|
||||
data["dates"][missingdate][ty][url] = []
|
||||
|
||||
data["dates"][missingdate][ty][url].append([
|
||||
"00:00:00",
|
||||
"schedule",
|
||||
fn,
|
||||
missingtask
|
||||
])
|
||||
|
||||
# Or else it's a checklist whether been checked or unchecked
|
||||
|
||||
else:
|
||||
if "[V]" in done:
|
||||
done = done.replace(" [V]", "").split("=:>")
|
||||
check = True
|
||||
else:
|
||||
done = done.replace(" [ ]", "").split("=:>")
|
||||
check = False
|
||||
|
||||
# Putting the thing into the data
|
||||
|
||||
if not date in data["dates"]:
|
||||
data["dates"][date] = {}
|
||||
|
||||
if not ty in data["dates"][date]:
|
||||
data["dates"][date][ty] = {}
|
||||
|
||||
if not url in data["dates"][date][ty]:
|
||||
data["dates"][date][ty][url] = []
|
||||
|
||||
data["dates"][date][ty][url].append([
|
||||
time,
|
||||
"history",
|
||||
fn,
|
||||
"[Checklist]",
|
||||
[
|
||||
done,
|
||||
check
|
||||
]
|
||||
])
|
||||
|
||||
# Now let's add all the others.
|
||||
|
||||
else:
|
||||
if not date in data["dates"]:
|
||||
data["dates"][date] = {}
|
||||
|
||||
if not ty in data["dates"][date]:
|
||||
data["dates"][date][ty] = {}
|
||||
|
||||
if not url in data["dates"][date][ty]:
|
||||
data["dates"][date][ty][url] = []
|
||||
|
||||
data["dates"][date][ty][url].append([
|
||||
time,
|
||||
"history",
|
||||
fn,
|
||||
done
|
||||
])
|
||||
|
||||
#print(ty, url, fn, done)
|
||||
|
||||
|
||||
|
||||
|
||||
data_save(data)
|
||||
return data
|
||||
|
||||
def data_save(data):
|
||||
|
||||
# This function will save the data to the /set folder. It will include a
|
||||
# a whole lot of inforamtion. Basically all analytics data will be there.
|
||||
|
||||
new_date_format = "%Y/%m/%d"
|
||||
|
||||
lines = []
|
||||
|
||||
lines.append("##################### VCStudio Analytics File #####################")
|
||||
lines.append("")
|
||||
lines.append(" Last update: "+datetime.datetime.strftime(datetime.datetime.today(), new_date_format))
|
||||
lines.append("")
|
||||
lines.append(" Project : "+data["name"])
|
||||
lines.append(" Director: "+data["director"])
|
||||
lines.append(" Comment : "+data["status"])
|
||||
lines.append("")
|
||||
lines.append(" From: "+data["startdate"]+" To: "+data["deadline"])
|
||||
lines.append("")
|
||||
lines.append("-------------------------------------------------------------------")
|
||||
lines.append("")
|
||||
lines.append(" CURREND PROGRESS : "+str(data["fraction"]*100)+"%")
|
||||
lines.append("")
|
||||
lines.append(" Current actuall : "+str(data["donework"]*100)+"%")
|
||||
lines.append(" Current checklist : "+str(data["checklist"]*100)+"%")
|
||||
lines.append("")
|
||||
lines.append(" Current Characters: "+str(data["chr"]*100)+"%")
|
||||
lines.append(" Current Vehicled : "+str(data["veh"]*100)+"%")
|
||||
lines.append(" Current Locations : "+str(data["loc"]*100)+"%")
|
||||
lines.append(" Current Other(obj): "+str(data["obj"]*100)+"%")
|
||||
lines.append(" Current Scenes : "+str(data["rnd"]*100)+"%")
|
||||
lines.append("")
|
||||
lines.append("-------------------------------------------------------------------")
|
||||
lines.append("")
|
||||
lines.append(" Bias:")
|
||||
lines.append(" Characters: X "+str(data["chr_factor"]))
|
||||
lines.append(" Vehicled : X "+str(data["veh_factor"]))
|
||||
lines.append(" Locations : X "+str(data["loc_factor"]))
|
||||
lines.append(" Other(obj): X "+str(data["obj_factor"]))
|
||||
lines.append(" Scenes : X "+str(data["rnd_factor"]))
|
||||
lines.append("")
|
||||
lines.append("##################### Schedule / History #####################")
|
||||
lines.append("")
|
||||
|
||||
for date in sorted(data["dates"]):
|
||||
lines.append(" "+date)
|
||||
|
||||
date = data["dates"][date]
|
||||
|
||||
if "fractions" in date:
|
||||
lines.append("")
|
||||
lines.append(" Actuall : "+str(date["fractions"]["project"]*100)+"%")
|
||||
lines.append("")
|
||||
lines.append(" Characters: "+str(date["fractions"]["chr"]*100)+"%")
|
||||
lines.append(" Vehicles : "+str(date["fractions"]["veh"]*100)+"%")
|
||||
lines.append(" Locations : "+str(date["fractions"]["loc"]*100)+"%")
|
||||
lines.append(" Other(obj): "+str(date["fractions"]["obj"]*100)+"%")
|
||||
lines.append(" Scenes : "+str(date["fractions"]["rnd"]*100)+"%")
|
||||
|
||||
for thing in ["assets", "scenes", "files"]:
|
||||
if thing in date:
|
||||
|
||||
lines.append("")
|
||||
lines.append(" ---- "+thing+" :")
|
||||
|
||||
for asset in sorted( date[thing] ):
|
||||
lines.append(" ---- "+asset+" : ")
|
||||
lines.append("")
|
||||
for task in date[thing][asset]:
|
||||
|
||||
|
||||
if task[1] == "schedule":
|
||||
lines.append(" "+task[0]+" "+task[1])
|
||||
lines.append(" "+task[2])
|
||||
lines.append("")
|
||||
spaces = " "
|
||||
for directory in task[3]:
|
||||
spaces = spaces + ":..."
|
||||
lines.append(spaces+directory)
|
||||
|
||||
elif task[3] == "[Checklist]":
|
||||
lines.append(" "+task[0]+" "+task[1]+" "+task[3])
|
||||
lines.append(" "+task[2])
|
||||
lines.append("")
|
||||
spaces = " "
|
||||
okay = " [Un-Checked]"
|
||||
if task[4][1]:
|
||||
okay = " [Checked]"
|
||||
for directory in task[4][0]:
|
||||
spaces = spaces + ":..."
|
||||
add_okay = ""
|
||||
if directory == task[4][0][-1]:
|
||||
add_okay = okay
|
||||
lines.append(spaces+directory+add_okay)
|
||||
|
||||
else:
|
||||
lines.append(" "+task[0]+" "+task[1]+" "+task[3])
|
||||
lines.append(" "+task[2])
|
||||
|
||||
lines.append("")
|
||||
|
||||
|
||||
lines.append("")
|
||||
lines.append("-------------------------------------------------------------------")
|
||||
lines.append("")
|
||||
|
||||
#test = open("/home/vcs/Desktop/testfile.vcsa", "w")
|
||||
|
||||
|
||||
for i in lines:
|
||||
print(i)
|
||||
#test.write(i+"\n")
|
||||
|
||||
#test.close()
|
||||
|
|
Loading…
Add table
Reference in a new issue