mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-10 20:42:21 +02:00
294 lines
8.7 KiB
Beef
294 lines
8.7 KiB
Beef
using System;
|
|
using System.Collections;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using Beefy;
|
|
|
|
namespace IDE
|
|
{
|
|
public class WakaTime
|
|
{
|
|
String mApiKey ~ delete _;
|
|
|
|
String mPythonLocation ~ delete _;
|
|
String mCurFilePath = new String() ~ delete _;
|
|
int32 mLastSendTicks;
|
|
Monitor mMonitor = new Monitor() ~ delete _;
|
|
|
|
public this(String key)
|
|
{
|
|
mApiKey = new String(key);
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
}
|
|
|
|
public void QueueFile(String filePath, String projectName, bool isWrite)
|
|
{
|
|
String useFilePath = filePath;
|
|
String useProjectName = projectName;
|
|
|
|
bool doSend = false;
|
|
if (mCurFilePath != useFilePath)
|
|
{
|
|
doSend = true;
|
|
}
|
|
else if (mLastSendTicks > 120*60)
|
|
{
|
|
doSend = true;
|
|
}
|
|
|
|
if (isWrite)
|
|
doSend = true;
|
|
mCurFilePath.Set(useFilePath);
|
|
|
|
if (doSend)
|
|
{
|
|
useFilePath = new String(useFilePath);
|
|
useProjectName = new String(useProjectName);
|
|
var me = this;
|
|
ThreadPool.QueueUserWorkItem(new () => me.SendFile(useFilePath, useProjectName, isWrite) ~ { delete useFilePath; delete useProjectName; });
|
|
mLastSendTicks = 0;
|
|
}
|
|
}
|
|
|
|
public void Update()
|
|
{
|
|
mLastSendTicks++;
|
|
}
|
|
|
|
public void getPythonDir(String pyDir)
|
|
{
|
|
getCurrentDirectory(pyDir);
|
|
pyDir.Append("\\Python");
|
|
}
|
|
|
|
public void getPython(String outPath)
|
|
{
|
|
|
|
doesPythonExist();
|
|
//return;
|
|
|
|
|
|
if (mPythonLocation != null)
|
|
{
|
|
outPath.Append(mPythonLocation);
|
|
return;
|
|
}
|
|
|
|
String[] locations = scope
|
|
.(
|
|
//"c:\\Python27\\python.exe",
|
|
|
|
"pythonw.exe",
|
|
"python",
|
|
"\\Python37\\pythonw",
|
|
"\\Python36\\pythonw",
|
|
"\\Python35\\pythonw",
|
|
"\\Python34\\pythonw",
|
|
"\\Python33\\pythonw",
|
|
"\\Python32\\pythonw",
|
|
"\\Python31\\pythonw",
|
|
"\\Python30\\pythonw",
|
|
"\\Python27\\pythonw",
|
|
"\\Python26\\pythonw",
|
|
"\\python37\\pythonw",
|
|
"\\python36\\pythonw",
|
|
"\\python35\\pythonw",
|
|
"\\python34\\pythonw",
|
|
"\\python33\\pythonw",
|
|
"\\python32\\pythonw",
|
|
"\\python31\\pythonw",
|
|
"\\python30\\pythonw",
|
|
"\\python27\\pythonw",
|
|
"\\python26\\pythonw",
|
|
"\\Python37\\python",
|
|
"\\Python36\\python",
|
|
"\\Python35\\python",
|
|
"\\Python34\\python",
|
|
"\\Python33\\python",
|
|
"\\Python32\\python",
|
|
"\\Python31\\python",
|
|
"\\Python30\\python",
|
|
"\\Python27\\python",
|
|
"\\Python26\\python",
|
|
"\\python37\\python",
|
|
"\\python36\\python",
|
|
"\\python35\\python",
|
|
"\\python34\\python",
|
|
"\\python33\\python",
|
|
"\\python32\\python",
|
|
"\\python31\\python",
|
|
"\\python30\\python",
|
|
"\\python27\\python",
|
|
"\\python26\\python"
|
|
);
|
|
for (String location in locations)
|
|
{
|
|
if (location.Contains('\\'))
|
|
{
|
|
String dirName = scope String();
|
|
Path.GetDirectoryPath(location, dirName);
|
|
if (!Directory.Exists(dirName))
|
|
continue;
|
|
}
|
|
|
|
ProcessStartInfo procInfo = scope ProcessStartInfo();
|
|
procInfo.UseShellExecute = false;
|
|
procInfo.RedirectStandardError = true;
|
|
procInfo.RedirectStandardOutput = true;
|
|
procInfo.SetFileName(location);
|
|
procInfo.CreateNoWindow = true;
|
|
procInfo.SetArguments("--version");
|
|
|
|
Debug.WriteLine("ProcStartInfo {0} Verb: {1}", procInfo, procInfo.[Friend]mVerb);
|
|
|
|
/*Process process = null;
|
|
if (!case .Ok(out process) = Process.Start(procInfo))
|
|
continue;
|
|
defer(scope) delete process;
|
|
String errors = scope String();
|
|
if (case .Err = process.StandardError.ReadToEnd(errors))
|
|
continue;*/
|
|
|
|
String resultStr = scope String();
|
|
SpawnedProcess process = scope SpawnedProcess();
|
|
if (process.Start(procInfo) case .Err)
|
|
continue;
|
|
|
|
FileStream fileStream = scope FileStream();
|
|
process.AttachStandardError(fileStream);
|
|
StreamReader streamReader = scope StreamReader(fileStream, null, false, 4096);
|
|
streamReader.ReadToEnd(resultStr).IgnoreError();
|
|
|
|
if (resultStr.IsEmpty)
|
|
{
|
|
FileStream fileStreamOut = scope FileStream();
|
|
process.AttachStandardOutput(fileStreamOut);
|
|
StreamReader streamReaderOut = scope StreamReader(fileStreamOut, null, false, 4096);
|
|
streamReaderOut.ReadToEnd(resultStr).IgnoreError();
|
|
}
|
|
|
|
//TODO: This 'errors' check is not correct, but also it seems that we're getting stdout data in stderr... (?)
|
|
if ((resultStr != null) && (resultStr != ""))
|
|
{
|
|
mPythonLocation = new String(location);
|
|
outPath.Append(mPythonLocation);
|
|
return;
|
|
}
|
|
}
|
|
|
|
mPythonLocation = new String("");// Give up
|
|
|
|
return;
|
|
}
|
|
|
|
void GetCLI(String cliPath)
|
|
{
|
|
cliPath.Append(BFApp.sApp.mInstallDir, "wakatime-master/wakatime/cli.py");
|
|
}
|
|
|
|
SpawnedProcess mProcess ~ delete _;
|
|
|
|
public void SendFile(String fileName, String projectName, bool isWrite)
|
|
{
|
|
using (mMonitor.Enter())
|
|
{
|
|
DoSendFile(fileName, projectName, isWrite);
|
|
}
|
|
}
|
|
|
|
public void DoSendFile(String fileName, String projectName, bool isWrite)
|
|
{
|
|
Debug.WriteLine("WakaTime: {0} proj: {1} isWrite: {2} ThreadId: {3} Tick: {4}", fileName, projectName, isWrite, Thread.CurrentThread.Id, (int32)Platform.BfpSystem_TickCount());
|
|
|
|
String arguments = scope String();
|
|
arguments.Append("\"");
|
|
GetCLI(arguments);
|
|
arguments.Append("\" --key=\"", mApiKey, "\"",
|
|
" --file=\"", fileName, "\"",
|
|
" --plugin=\"Beef\"");
|
|
|
|
if (!String.IsNullOrWhiteSpace(projectName))
|
|
arguments.Append(" --project=\"", projectName, "\"");
|
|
|
|
if (isWrite)
|
|
arguments.Append(" --write");
|
|
|
|
ProcessStartInfo procInfo = scope ProcessStartInfo();
|
|
procInfo.UseShellExecute = false;
|
|
String pyPath = scope String();
|
|
getPython(pyPath);
|
|
if (String.IsNullOrEmpty(pyPath))
|
|
return;
|
|
procInfo.SetFileName(pyPath);
|
|
procInfo.CreateNoWindow = true;
|
|
procInfo.SetArguments(arguments);
|
|
|
|
|
|
|
|
//for (int i = 0; i < 10; i++)
|
|
{
|
|
//Debug.WriteLine("ProcStartInfo {0} Dir: {1} Verb: {2}", procInfo, procInfo.mDirectory, procInfo.mVerb);
|
|
|
|
delete mProcess;
|
|
mProcess = new SpawnedProcess();
|
|
if (mProcess.Start(procInfo) case .Err)
|
|
{
|
|
delete mProcess;
|
|
mProcess = null;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Check if wakatime command line exists or not
|
|
bool doesCLIExist()
|
|
{
|
|
String path = scope String();
|
|
GetCLI(path);
|
|
if (File.Exists(path))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// Check if bundled python installation exists
|
|
bool doesPythonExist()
|
|
{
|
|
String path = scope String();
|
|
getPythonDir(path);
|
|
path.Append("\\pythonw.exe");
|
|
if (File.Exists(path))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
|
|
/// Check if python is installed
|
|
bool isPythonInstalled()
|
|
{
|
|
String pyPath = scope String();
|
|
getPython(pyPath);
|
|
if (String.IsNullOrEmpty(pyPath))
|
|
{
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/// Returns current working dir
|
|
static public void getCurrentDirectory(String outDir)
|
|
{
|
|
var exePath = scope String();
|
|
Environment.GetExecutableFilePath(exePath);
|
|
Path.GetDirectoryPath(exePath, outDir);
|
|
}
|
|
}
|
|
}
|