Migrated to new baseline
This commit is contained in:
parent
84db9660f1
commit
c742979250
@ -1,6 +1,36 @@
|
||||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<configuration>
|
||||
<configSections>
|
||||
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
|
||||
<section name="AutoLikerCefSharpWpf.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
|
||||
</sectionGroup>
|
||||
</configSections>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
|
||||
</startup>
|
||||
<userSettings>
|
||||
<AutoLikerCefSharpWpf.Properties.Settings>
|
||||
<setting name="Instagram_Hashtag" serializeAs="String">
|
||||
<value>travelphotography,familyphotographer</value>
|
||||
</setting>
|
||||
<setting name="DelayRestartMin" serializeAs="String">
|
||||
<value>45</value>
|
||||
</setting>
|
||||
<setting name="DelayRestartMax" serializeAs="String">
|
||||
<value>60</value>
|
||||
</setting>
|
||||
<setting name="LikesMin" serializeAs="String">
|
||||
<value>10</value>
|
||||
</setting>
|
||||
<setting name="LikesMax" serializeAs="String">
|
||||
<value>25</value>
|
||||
</setting>
|
||||
<setting name="DelayMin" serializeAs="String">
|
||||
<value>5</value>
|
||||
</setting>
|
||||
<setting name="DelayMax" serializeAs="String">
|
||||
<value>15</value>
|
||||
</setting>
|
||||
</AutoLikerCefSharpWpf.Properties.Settings>
|
||||
</userSettings>
|
||||
</configuration>
|
||||
277
AutoLikerCefSharpWpf/Assets/autotag_injection.js
Normal file
277
AutoLikerCefSharpWpf/Assets/autotag_injection.js
Normal file
@ -0,0 +1,277 @@
|
||||
// https://jscompress.com/
|
||||
|
||||
function alObject() {
|
||||
this._tag = "";
|
||||
this._posts = {};
|
||||
this._maxLikes = 3;
|
||||
this._likesMin = 5;
|
||||
this._likesMax = 10;
|
||||
this._delayRestart = 15; // minutes
|
||||
this._delayRestartMin = 15; // minutes
|
||||
this._delayRestartMax = 30; // minutes
|
||||
this._delayPerLikeMin = 5; // seconds
|
||||
this._delayPerLikeMax = 10; // seconds
|
||||
this._endCursor = ""; // needed?
|
||||
this._failedRetriesMax = 2;
|
||||
this._failedRetries = 0;
|
||||
this._instagramBaseUrl = "https://www.instagram.com";
|
||||
this._postItems = [];
|
||||
this._scrollOffset = null;
|
||||
}
|
||||
|
||||
alObject.prototype.initializeSettings = function(tag, likesMin, likesMax, delayMin, delayMax, delayRestartMin, delayRestartMax) {
|
||||
this._tag = tag;
|
||||
this._likesMin = likesMin;
|
||||
this._likesMax = likesMax;
|
||||
this._delayPerLikeMin = delayMin;
|
||||
this._delayPerLikeMax = delayMax;
|
||||
this._delayRestartMin = delayRestartMin;
|
||||
this._delayRestartMax = delayRestartMax;
|
||||
console.log("tag:" + tag + " | likesMin:" + likesMin + " | likesMax:" + likesMax + " | delayMin: " + delayMin + " | delayMax: " + delayMax + " | delayRestartMin: " + delayRestartMin + " | delayRestartMax: " + delayRestartMax);
|
||||
this._maxLikes = this.getRandomInt(this._likesMin, this._likesMax);
|
||||
this._delayRestart = this.getRandomInt(this._delayRestartMin, this._delayRestartMax);
|
||||
console.log("_maxLikes: " + this._maxLikes);
|
||||
console.log("_delayRestart (min): " + this._delayRestart);
|
||||
if (this._tag.includes(",")) {
|
||||
let tags = this._tag.split(",");
|
||||
console.log(tags);
|
||||
console.log("tags length: " + tags.length);
|
||||
let pick = this.getRandomInt(0, tags.length - 1);
|
||||
let picked_tag = tags[pick].trim();
|
||||
console.log("picked tag: " + picked_tag);
|
||||
this._tag = picked_tag;
|
||||
}
|
||||
}
|
||||
|
||||
alObject.prototype.instagramStartClickProcess = function(retry=true) {
|
||||
let thisObj = this;
|
||||
thisObj._postItems = [];
|
||||
console.log('*** instagramStartClickProcess ***');
|
||||
window.scrollTo(0,0);
|
||||
thisObj.runDelay(10000, () => {
|
||||
thisObj.log((new Date()).toLocaleString() + ': Starting click process ..');
|
||||
let top_posts = jQuery('h2').eq(0);
|
||||
let most_recent = jQuery('h2').eq(1);
|
||||
let jump_to_section = null;
|
||||
if (most_recent.length > 0) {
|
||||
jump_to_section = most_recent;
|
||||
} else if (most_recent.length == 0 && top_posts.length > 0) {
|
||||
jump_to_section = top_posts;
|
||||
}
|
||||
|
||||
if (jump_to_section == null || jump_to_section == 0) {
|
||||
thisObj.log('ERROR: couldn\'t find most recent or top posts sections!');
|
||||
if (retry) {
|
||||
thisObj.log(' - retrying after 60 seconds (to give IG time to load).');
|
||||
thisObj.runDelay(60000, () => {
|
||||
thisObj.instagramStartClickProcess(false);
|
||||
});
|
||||
} else {
|
||||
thisObj.runDelay(1000, () => {
|
||||
thisObj.restartProcess();
|
||||
});
|
||||
}
|
||||
|
||||
} else {
|
||||
let mr_div = jump_to_section.next();
|
||||
thisObj.log('Scroll to list ..');
|
||||
jQuery('html, body').animate({ scrollTop: mr_div.offset().top }, 500);
|
||||
let parentX = mr_div.offset().left;
|
||||
let parentY = mr_div.offset().top;
|
||||
thisObj._scrollOffset = mr_div.offset();
|
||||
console.log('parentX: ' + parentX + ' ; parentY: ' + parentY);
|
||||
thisObj.runDelay(2000, () => {
|
||||
let child01 = mr_div.children('div').eq(0);
|
||||
let postLinks = child01.find('a');
|
||||
postLinks.each( function(i) {
|
||||
thisObj._postItems.push(jQuery(this).attr('href'));
|
||||
});
|
||||
console.log('items:');
|
||||
console.log(thisObj._postItems);
|
||||
thisObj.log('Found posts: ' + thisObj._postItems.length);
|
||||
// get first post
|
||||
let element01 = jQuery('a[href="' + thisObj._postItems[0] + '"]');
|
||||
console.log(element01);
|
||||
let element02 = element01.find('img').eq(0);
|
||||
console.log(element02);
|
||||
console.log(element02.attr('src'));
|
||||
if (element02) {
|
||||
console.log('imgX: ' + element02.offset().left + ' ; imgY: ' + element02.offset().top);
|
||||
//let clickX = parseInt(parentX - element02.offset().left) + 1;
|
||||
let clickX = parseInt(element02.offset().left) + 30;
|
||||
let clickY = parseInt(parentY - element02.offset().top) + 60;
|
||||
console.log('clickX: ' + clickX + ' ; clickY: ' + clickY);
|
||||
thisObj.log('Will like this many posts: ' + thisObj._maxLikes);
|
||||
thisObj.instagramClickPost(element02, clickX, clickY);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
alObject.prototype.instagramClickPost = function(img, x, y) {
|
||||
let thisObj = this;
|
||||
thisObj.log('Click on initial post ..');
|
||||
boundAsync.singleLeftClick(x, y).then( (res1) => {
|
||||
console.log('Left Click');
|
||||
//console.log('jQuery(window).scrollLeft(): ' + jQuery(window).scrollLeft() + ' ; jQuery(window).scrollTop(): ' + jQuery(window).scrollTop());
|
||||
thisObj.runDelay(8000, () => {
|
||||
thisObj.instagramLoopOverPostsClick();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
alObject.prototype.instagramLoopOverPostsClick = function(index) {
|
||||
let thisObj = this;
|
||||
// initial index
|
||||
if (!index) {
|
||||
index = 1;
|
||||
}
|
||||
thisObj.log("Like post; " + index + " of " + thisObj._maxLikes);
|
||||
// like button
|
||||
//let likeBtn = jQuery('body').find('span._aamw button._abl-').eq(0); // Update: 2022-06-11
|
||||
let likeBtn = jQuery('body').find('span._aamw span:has(svg)').eq(0); // Update: 2023-09-12
|
||||
console.log('likeBtn:');
|
||||
console.log(likeBtn);
|
||||
// next button
|
||||
//let nextBtn = jQuery('a.coreSpriteRightPaginationArrow').eq(0);
|
||||
//let nextBtn = jQuery('div.l8mY4 button.wpO6b');
|
||||
let nextBtn = jQuery('div._aaqg button._abl-');
|
||||
console.log('nextBtn:');
|
||||
console.log(nextBtn);
|
||||
// check if like button exists, if not restart
|
||||
if (likeBtn.length == 0) {
|
||||
thisObj.log(' - Could not find the "Like" button :(');
|
||||
if (nextBtn.length > 0) {
|
||||
thisObj.instagramClickNextButton(nextBtn, index);
|
||||
} else {
|
||||
thisObj.restartProcess();
|
||||
}
|
||||
}
|
||||
// offsets and coordinates
|
||||
let btnOffset = likeBtn.offset();
|
||||
let clickY = parseInt(btnOffset.top - jQuery(window).scrollTop());
|
||||
let clickX = parseInt(btnOffset.left - jQuery(window).scrollLeft());
|
||||
console.log('likeBtn = clickX: ' + clickX + ' ; clickY: ' + clickY);
|
||||
// like text
|
||||
//let likeSpan = likeBtn.children().eq(0);
|
||||
let likeImage = likeBtn.find('svg').eq(0);
|
||||
let likeText = likeImage.attr('aria-label');
|
||||
console.log('Like Text: ' + likeText);
|
||||
if (likeText === 'Like') {
|
||||
// post hasn't been liked yet
|
||||
// generate delay
|
||||
let delayBeforeLike = thisObj.getRandomInt(thisObj._delayPerLikeMin, thisObj._delayPerLikeMax);
|
||||
let delayBeforeLikeMs = delayBeforeLike * 1000;
|
||||
thisObj.log(" - not liked yet; delay before clicking like = " + delayBeforeLike + " sec");
|
||||
// delay like
|
||||
thisObj.runDelay(delayBeforeLikeMs, () => {
|
||||
thisObj.log(" - initiating clicking Like button ..");
|
||||
boundAsync.singleLeftClick(clickX+10, clickY+10).then( result => {
|
||||
thisObj.log(" - clicked Like button .. wait to confirm ..");
|
||||
// check if post is actually liked
|
||||
thisObj.runDelay(4000, () => {
|
||||
likeText = jQuery('body').find('span._aamw svg').eq(0).attr('aria-label'); // Update: 2023-09-12
|
||||
console.log('Like Text: ' + likeText);
|
||||
if (likeText !== 'Like') {
|
||||
thisObj.log(" - Successfully liked!");
|
||||
thisObj.instagramClickNextButton(nextBtn, index);
|
||||
} else {
|
||||
// POST NOT LIKED! POTENTIALLY DUE TO INSTAGRAM BLOCK
|
||||
// Stop processing
|
||||
thisObj.log(" - POST NOT LIKED! BLOCKED??");
|
||||
thisObj.log("*** STOPPING ***");
|
||||
thisObj.restartProcess();
|
||||
}
|
||||
});
|
||||
}, reason => {
|
||||
thisObj.log(" - Error liking! Reason = " + reason);
|
||||
thisObj.instagramClickNextButton(nextBtn, index);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// already liked, go to the next item
|
||||
thisObj.log(" - already liked this post!");
|
||||
thisObj.instagramClickNextButton(nextBtn, index);
|
||||
}
|
||||
}
|
||||
|
||||
alObject.prototype.instagramClickNextButton = function(nextBtn, i) {
|
||||
let thisObj = this;
|
||||
if (i < thisObj._maxLikes) {
|
||||
thisObj.log(" - Waiting before clicking on next button ..");
|
||||
let nextBtnOffset = nextBtn.offset();
|
||||
console.log(nextBtnOffset);
|
||||
let nextY = parseInt(nextBtnOffset.top - jQuery(window).scrollTop());
|
||||
let nextX = parseInt(nextBtnOffset.left - jQuery(window).scrollLeft());
|
||||
console.log('nextBtn = nextX: ' + nextX + ' ; nextY: ' + nextY);
|
||||
thisObj.runDelay(3000, () => {
|
||||
boundAsync.singleLeftClick(nextX+10, nextY+10).then(result => {
|
||||
thisObj.log(" - Successfully went to the next post! Wait 5 sec ..");
|
||||
thisObj.runDelay(5000, () => {
|
||||
let newIndex = i + 1;
|
||||
thisObj.instagramLoopOverPostsClick(newIndex);
|
||||
});
|
||||
}, reason => {
|
||||
thisObj.log(" - Error going to the next post! Reason = " + reason);
|
||||
});
|
||||
});
|
||||
} else {
|
||||
thisObj.log(" - Reached end of list of posts, restarting process ..");
|
||||
thisObj.runDelay(3000, () => {
|
||||
thisObj.restartProcess();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
alObject.prototype.restartProcess = function() {
|
||||
let thisObj = this;
|
||||
console.log('*** restartProcess ***');
|
||||
if (boundAsync) {
|
||||
let restart;
|
||||
if (thisObj._delayRestart) {
|
||||
restart = thisObj._delayRestart;
|
||||
} else {
|
||||
restart = 15;
|
||||
}
|
||||
let restartMs = restart * 60000;
|
||||
let nowDate = new Date();
|
||||
var newDateObj = new Date(nowDate.getTime() + restartMs);
|
||||
thisObj.log(nowDate.toLocaleString() + ": RESTARTING in (min): " + restart);
|
||||
thisObj.log(" - Reloading at: " + newDateObj.toLocaleString());
|
||||
thisObj.runDelay(restartMs, () => {
|
||||
boundAsync.restartProcess().then(result => {
|
||||
console.log('reloading ..');
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Delay function
|
||||
**/
|
||||
alObject.prototype.runDelay = function(Delay, CallbackFunc) {
|
||||
setTimeout(CallbackFunc, Delay);
|
||||
}
|
||||
|
||||
/**
|
||||
* Logging function
|
||||
**/
|
||||
alObject.prototype.log = function(msg) {
|
||||
console.log(msg);
|
||||
if (boundAsync) {
|
||||
boundAsync.logMessage(msg).then(result => {
|
||||
// successful result
|
||||
}, reason => {
|
||||
console.error(reason);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a random integer between min (inclusive) and max (inclusive)
|
||||
* Using Math.round() will give you a non-uniform distribution!
|
||||
*/
|
||||
alObject.prototype.getRandomInt = function(min, max) {
|
||||
return Math.floor(Math.random() * (max - min + 1)) + min;
|
||||
}
|
||||
1
AutoLikerCefSharpWpf/Assets/autotag_injection_min.js
Normal file
1
AutoLikerCefSharpWpf/Assets/autotag_injection_min.js
Normal file
File diff suppressed because one or more lines are too long
@ -115,6 +115,10 @@
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
</ApplicationDefinition>
|
||||
<Compile Include="Helper\AutoLikerSettingsManager.cs" />
|
||||
<Compile Include="Helper\JavaScriptBoundObject.cs" />
|
||||
<Compile Include="Helper\JavaScriptProcessor.cs" />
|
||||
<Compile Include="Settings.cs" />
|
||||
<Page Include="MainWindow.xaml">
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
<SubType>Designer</SubType>
|
||||
@ -177,6 +181,10 @@
|
||||
<ItemGroup>
|
||||
<Resource Include="Resources\autoliker-512.ico" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Assets\autotag_injection.js" />
|
||||
<EmbeddedResource Include="Assets\autotag_injection_min.js" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
|
||||
@ -13,7 +13,7 @@ namespace AutoLikerCefSharpWpf.Converter
|
||||
#endif
|
||||
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return "AutoLikerCefSharpWpf (" + Build + ") - " + (value ?? "No Title Specified");
|
||||
return "AutoLiker v2 (" + Build + ") - " + (value ?? "No Title Specified");
|
||||
}
|
||||
|
||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
|
||||
80
AutoLikerCefSharpWpf/Helper/AutoLikerSettingsManager.cs
Normal file
80
AutoLikerCefSharpWpf/Helper/AutoLikerSettingsManager.cs
Normal file
@ -0,0 +1,80 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.Windows.Controls;
|
||||
|
||||
namespace AutoLikerCefSharpWpf.Helper
|
||||
{
|
||||
internal class AutoLikerSettingsManager
|
||||
{
|
||||
private MainWindow main;
|
||||
|
||||
public AutoLikerSettingsManager(MainWindow win) {
|
||||
this.main = win;
|
||||
this.InitializeSettings();
|
||||
}
|
||||
|
||||
private void InitializeSettings()
|
||||
{
|
||||
main.txtHashTag.Text = Properties.Settings.Default.Instagram_Hashtag;
|
||||
main.txtDelayRestartMin.Text = Properties.Settings.Default.DelayRestartMin.ToString();
|
||||
main.txtDelayRestartMax.Text = Properties.Settings.Default.DelayRestartMax.ToString();
|
||||
main.txtMaxLikesMin.Text = Properties.Settings.Default.LikesMin.ToString();
|
||||
main.txtMaxLikesMax.Text = Properties.Settings.Default.LikesMax.ToString();
|
||||
main.txtDelayMin.Text = Properties.Settings.Default.DelayMin.ToString();
|
||||
main.txtDelayMax.Text = Properties.Settings.Default.DelayMax.ToString();
|
||||
this.ToggleSettingsSaveButton(false);
|
||||
|
||||
// assign handlers
|
||||
main.txtHashTag.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtDelayRestartMin.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtDelayRestartMax.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtMaxLikesMin.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtMaxLikesMax.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtDelayMin.TextChanged += Al_Settings_TextChanged;
|
||||
main.txtDelayMax.TextChanged += Al_Settings_TextChanged;
|
||||
}
|
||||
|
||||
private void Al_Settings_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||
{
|
||||
TextBox tb = (TextBox)sender;
|
||||
Debug.WriteLine("Setting changed: " + tb.Name + " = " + tb.Text);
|
||||
this.ToggleSettingsSaveButton(true);
|
||||
}
|
||||
|
||||
private void ToggleSettingsSaveButton(bool enable)
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
main.btnSaveSettings.IsEnabled = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
main.btnSaveSettings.IsEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
public void AutoTagSettingsSave()
|
||||
{
|
||||
int.TryParse(main.txtDelayRestartMin.Text, out int delayRestartMin);
|
||||
int.TryParse(main.txtDelayRestartMax.Text, out int delayRestartMax);
|
||||
int.TryParse(main.txtMaxLikesMin.Text, out int likesMin);
|
||||
int.TryParse(main.txtMaxLikesMax.Text, out int likesMax);
|
||||
int.TryParse(main.txtDelayMin.Text, out int delayMin);
|
||||
int.TryParse(main.txtDelayMax.Text, out int delayMax);
|
||||
|
||||
Properties.Settings.Default.Instagram_Hashtag = main.txtHashTag.Text;
|
||||
Properties.Settings.Default.DelayRestartMin = delayRestartMin;
|
||||
Properties.Settings.Default.DelayRestartMax = delayRestartMax;
|
||||
Properties.Settings.Default.LikesMin = likesMin;
|
||||
Properties.Settings.Default.LikesMax = likesMax;
|
||||
Properties.Settings.Default.DelayMin = delayMin;
|
||||
Properties.Settings.Default.DelayMax = delayMax;
|
||||
|
||||
Properties.Settings.Default.Save();
|
||||
|
||||
main.LogMessage("Settings saved: " + DateTime.Now);
|
||||
|
||||
ToggleSettingsSaveButton(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
79
AutoLikerCefSharpWpf/Helper/JavaScriptBoundObject.cs
Normal file
79
AutoLikerCefSharpWpf/Helper/JavaScriptBoundObject.cs
Normal file
@ -0,0 +1,79 @@
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace AutoLikerCefSharpWpf.Helper
|
||||
{
|
||||
internal class JavaScriptBoundObject
|
||||
{
|
||||
private MainWindow Main;
|
||||
|
||||
public JavaScriptBoundObject(MainWindow win)
|
||||
{
|
||||
this.Main = win;
|
||||
}
|
||||
|
||||
public void SingleLeftClick(int x, int y)
|
||||
{
|
||||
Debug.WriteLine("SingleLeftClick: x = " + x + " ; y = " + y);
|
||||
MouseMoveEvent(x, y); // first move mouse to button
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.None);
|
||||
System.Threading.Thread.Sleep(100);
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);
|
||||
}
|
||||
|
||||
public void DoubleLeftClick(int x, int y)
|
||||
{
|
||||
Debug.WriteLine("DoubleLeftClick: x = " + x + " ; y = " + y);
|
||||
this.Main.Browser.GetBrowserHost().SendMouseClickEvent(x, y, MouseButtonType.Left, false, 1, CefEventFlags.LeftMouseButton);
|
||||
this.Main.Browser.GetBrowserHost().SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);
|
||||
this.Main.Browser.GetBrowserHost().SendMouseClickEvent(x, y, MouseButtonType.Left, false, 2, CefEventFlags.LeftMouseButton);
|
||||
this.Main.Browser.GetBrowserHost().SendMouseClickEvent(x, y, MouseButtonType.Left, true, 1, CefEventFlags.None);
|
||||
}
|
||||
|
||||
public void SingleRightClick(int x, int y)
|
||||
{
|
||||
Debug.WriteLine("SingleRightClick: x = " + x + " ; y = " + y);
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, false, 1, CefEventFlags.None);
|
||||
System.Threading.Thread.Sleep(100);
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseClickEvent(x, y, MouseButtonType.Right, true, 1, CefEventFlags.None);
|
||||
}
|
||||
|
||||
public void MouseMoveEvent(int x, int y)
|
||||
{
|
||||
Debug.WriteLine("MouseMoveEvent: x = " + x + " ; y = " + y);
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseMoveEvent(x, y, false, CefEventFlags.None);
|
||||
Thread.Sleep(50);
|
||||
}
|
||||
|
||||
public void MouseScrollEvent(int mouseX, int mouseY, int scrollX, int scrollY)
|
||||
{
|
||||
Debug.WriteLine($"MouseScrollEvent: mouseX={mouseX}, mouseY={mouseY}, scrollX={scrollX}, scrollY={scrollY}");
|
||||
this.Main.Browser.GetBrowser().GetHost().SendMouseWheelEvent(mouseX, mouseY, scrollX, scrollY, CefEventFlags.None);
|
||||
Thread.Sleep(300);
|
||||
}
|
||||
|
||||
public void KeyEscape()
|
||||
{
|
||||
KeyEvent k = new KeyEvent();
|
||||
k.WindowsKeyCode = (int)Key.Escape;
|
||||
this.Main.Browser.GetBrowser().GetHost().SendKeyEvent(k);
|
||||
}
|
||||
|
||||
public void LogMessage(string msg)
|
||||
{
|
||||
this.Main.LogMessage(msg);
|
||||
}
|
||||
|
||||
public void RestartProcess()
|
||||
{
|
||||
//this.Main.LoadInstragramTag();
|
||||
}
|
||||
}
|
||||
}
|
||||
65
AutoLikerCefSharpWpf/Helper/JavaScriptProcessor.cs
Normal file
65
AutoLikerCefSharpWpf/Helper/JavaScriptProcessor.cs
Normal file
@ -0,0 +1,65 @@
|
||||
using System;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AutoLikerCefSharpWpf.Helper
|
||||
{
|
||||
internal class JavaScriptProcessor
|
||||
{
|
||||
private const string autoTagJavaScriptFilename = "autotag_injection.js";
|
||||
private const string assetsNamespace = "AutoLikerCefSharpWpf.Assets.";
|
||||
|
||||
public static string PopulateJavaScriptFile(string tag, string posts, string cursor, string maxLikes, string delayPerLikeMin, string delayPerLikeMax)
|
||||
{
|
||||
string contents = ReturnJavaScriptFromFile(autoTagJavaScriptFilename);
|
||||
|
||||
if (contents != null)
|
||||
{
|
||||
contents = contents.Replace("{tag}", tag);
|
||||
contents = contents.Replace("{posts}", posts);
|
||||
contents = contents.Replace("{maxLikes}", maxLikes);
|
||||
contents = contents.Replace("{delayPerLikeMin}", delayPerLikeMin);
|
||||
contents = contents.Replace("{delayPerLikeMax}", delayPerLikeMax);
|
||||
contents = contents.Replace("{cursor}", cursor);
|
||||
}
|
||||
|
||||
return contents;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Load a JS file from the filesystem
|
||||
///
|
||||
/// Make sure that it is set to "Build Action" = "Embedded Resource"
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
/// <returns></returns>
|
||||
public static string ReturnJavaScriptFromFile(string filename)
|
||||
{
|
||||
string readContents = null;
|
||||
var assembly = Assembly.GetExecutingAssembly();
|
||||
try
|
||||
{
|
||||
if (filename == null)
|
||||
{
|
||||
filename = autoTagJavaScriptFilename;
|
||||
}
|
||||
|
||||
var resourceName = assetsNamespace + filename;
|
||||
|
||||
Debug.WriteLine(" :: get resource = " + resourceName);
|
||||
|
||||
using (Stream stream = assembly.GetManifestResourceStream(resourceName))
|
||||
using (StreamReader reader = new StreamReader(stream))
|
||||
{
|
||||
readContents = reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
catch (Exception error)
|
||||
{
|
||||
Debug.WriteLine("Exception: " + error.Message);
|
||||
}
|
||||
return readContents;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -7,48 +7,111 @@
|
||||
xmlns:behaviors="http://schemas.microsoft.com/xaml/behaviors"
|
||||
Title="{Binding Path=Title, ElementName=Browser, Converter={StaticResource TitleConverter}}"
|
||||
FocusManager.FocusedElement="{Binding ElementName=Browser}"
|
||||
WindowState="Maximized">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style TargetType="{x:Type Button}">
|
||||
<Setter Property="Margin" Value="2,5" />
|
||||
</Style>
|
||||
<Style TargetType="{x:Type TextBox}">
|
||||
<Setter Property="Margin" Value="2,5" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Content="Back" Command="{Binding WebBrowser.BackCommand, ElementName=Browser}" Width="50"/>
|
||||
<Button Content="Forward" Command="{Binding WebBrowser.ForwardCommand, ElementName=Browser}" Grid.Column="1" Width="60"/>
|
||||
<TextBox x:Name="txtBoxAddress" Text="{Binding Address, ElementName=Browser, FallbackValue=www.google.com}" Grid.Column="2" FontSize="12" BorderBrush="Gray" BorderThickness="1">
|
||||
<behaviors:Interaction.Behaviors>
|
||||
<behaviours:TextBoxBindingUpdateOnEnterBehaviour />
|
||||
</behaviors:Interaction.Behaviors>
|
||||
</TextBox>
|
||||
<Button Content="Print..." Command="{Binding WebBrowser.PrintCommand, ElementName=Browser}" Grid.Column="3" Width="50" />
|
||||
<Button Content="View source" Command="{Binding WebBrowser.ViewSourceCommand, ElementName=Browser}" Grid.Column="4" Width="75" />
|
||||
</Grid>
|
||||
<Border Grid.Row="1" BorderBrush="Gray" BorderThickness="0,1">
|
||||
<wpf:ChromiumWebBrowser x:Name="Browser"
|
||||
WindowState="Maximized"
|
||||
x:Name="AutoLikerWindow">
|
||||
<DockPanel>
|
||||
<DockPanel DockPanel.Dock="Left" Width="350px" Background="WhiteSmoke">
|
||||
|
||||
<Grid DockPanel.Dock="Top" Margin="5 5 5 5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="200" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Grid.Row="0" Grid.Column="0" Content="Hashtags - don't include # - comma-separated" x:Name="lblHashTag" />
|
||||
<Label Grid.Row="1" Grid.Column="0" Content="Maximum likes per page load" x:Name="lblMaxLikes" />
|
||||
<Label Grid.Row="2" Grid.Column="0" Content="Delay range between likes (sec)" x:Name="lblDelay" />
|
||||
<Label Grid.Row="3" Grid.Column="0" Content="Delay before reloading (min)" x:Name="lblDelayRestart" />
|
||||
<TextBox Grid.Column="1" Grid.Row="0" Margin="3" Height="50px" TextWrapping="Wrap" x:Name="txtHashTag"/>
|
||||
<StackPanel Grid.Column="1" Grid.Row="1" Margin="3" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<TextBox Width="40" x:Name="txtMaxLikesMin" />
|
||||
<Label Content="-" />
|
||||
<TextBox Width="40" x:Name="txtMaxLikesMax" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Grid.Row="2" Margin="3" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<TextBox Width="40" x:Name="txtDelayMin" />
|
||||
<Label Content="-" />
|
||||
<TextBox Width="40" x:Name="txtDelayMax" />
|
||||
</StackPanel>
|
||||
<StackPanel Grid.Column="1" Grid.Row="3" Margin="3" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<TextBox Width="40" x:Name="txtDelayRestartMin" />
|
||||
<Label Content="-" />
|
||||
<TextBox Width="40" x:Name="txtDelayRestartMax" />
|
||||
</StackPanel>
|
||||
<Button Grid.Column="1" Grid.Row="4" HorizontalAlignment="Left" MinWidth="80" Margin="3" Content="Save" x:Name="btnSaveSettings" Click="BtnSaveSettings_Click"/>
|
||||
</Grid>
|
||||
<StackPanel DockPanel.Dock="Top" HorizontalAlignment="Left" Orientation="Horizontal" Margin="0 5">
|
||||
<Button x:Name="btnStart" Height="35" Width="40" Content="Start" Margin="5 0 0 0" Click="BtnStart_Click"/>
|
||||
<Button x:Name="btnStop" Height="35" Width="40" Content="Stop" Margin="5 0 5 0" Click="BtnStop_Click"/>
|
||||
</StackPanel>
|
||||
<StackPanel DockPanel.Dock="Top" HorizontalAlignment="Left" Orientation="Horizontal">
|
||||
<Label Content="MouseX:" />
|
||||
<TextBox Margin="1" Width="75" x:Name="txtMouseX"/>
|
||||
<Label Content="MouseY:" />
|
||||
<TextBox Margin="1" Width="75" x:Name="txtMouseY"/>
|
||||
</StackPanel>
|
||||
<Grid DockPanel.Dock="Top" HorizontalAlignment="Stretch" Margin="5">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="24px" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBox Grid.Row="0" x:Name="txtLog" TextWrapping="Wrap" IsReadOnly="True"
|
||||
VerticalScrollBarVisibility="Auto" AcceptsReturn="True"/>
|
||||
<Label Grid.Row="1" x:Name="lblAppVersion" HorizontalContentAlignment="Left" Content="{Binding AutoLikerVersion, Mode=OneWay}"/>
|
||||
</Grid>
|
||||
|
||||
</DockPanel>
|
||||
<DockPanel DockPanel.Dock="Right" x:Name="browser_panel">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Grid>
|
||||
<Grid.Resources>
|
||||
<Style TargetType="{x:Type Button}">
|
||||
<Setter Property="Margin" Value="2,5" />
|
||||
</Style>
|
||||
<Style TargetType="{x:Type TextBox}">
|
||||
<Setter Property="Margin" Value="2,5" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Button Content="Back" Command="{Binding WebBrowser.BackCommand, ElementName=Browser}" Width="50"/>
|
||||
<Button Content="Forward" Command="{Binding WebBrowser.ForwardCommand, ElementName=Browser}" Grid.Column="1" Width="60"/>
|
||||
<TextBox x:Name="txtBoxAddress" Text="{Binding Address, ElementName=Browser, FallbackValue=www.google.com}" Grid.Column="2" FontSize="12" BorderBrush="Gray" BorderThickness="1">
|
||||
<behaviors:Interaction.Behaviors>
|
||||
<behaviours:TextBoxBindingUpdateOnEnterBehaviour />
|
||||
</behaviors:Interaction.Behaviors>
|
||||
</TextBox>
|
||||
<Button Content="Print..." Command="{Binding WebBrowser.PrintCommand, ElementName=Browser}" Grid.Column="3" Width="50" />
|
||||
<Button Content="DevTools" Click="Button_DevTools" Grid.Column="4" Width="60" />
|
||||
</Grid>
|
||||
<Border Grid.Row="1" BorderBrush="Gray" BorderThickness="0,1">
|
||||
<wpf:ChromiumWebBrowser x:Name="Browser"
|
||||
Address="https://www.google.com">
|
||||
<behaviors:Interaction.Behaviors>
|
||||
<behaviours:HoverLinkBehaviour x:Name="HoverLinkBehaviour"/>
|
||||
</behaviors:Interaction.Behaviors>
|
||||
</wpf:ChromiumWebBrowser>
|
||||
</Border>
|
||||
<ProgressBar IsIndeterminate="{Binding IsLoading, ElementName=Browser}"
|
||||
<behaviors:Interaction.Behaviors>
|
||||
<behaviours:HoverLinkBehaviour x:Name="HoverLinkBehaviour"/>
|
||||
</behaviors:Interaction.Behaviors>
|
||||
</wpf:ChromiumWebBrowser>
|
||||
</Border>
|
||||
<ProgressBar IsIndeterminate="{Binding IsLoading, ElementName=Browser}"
|
||||
HorizontalAlignment="Stretch"
|
||||
VerticalAlignment="Top"
|
||||
Width="Auto"
|
||||
@ -56,27 +119,29 @@
|
||||
Height="2"
|
||||
Visibility="{Binding IsLoading, ElementName=Browser, Converter={StaticResource BooleanToVisibilityConverter}}"
|
||||
BorderThickness="0" />
|
||||
<StatusBar Grid.Row="2" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="0">
|
||||
<TextBlock Text="{Binding HoverLink, ElementName=HoverLinkBehaviour}" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="1" />
|
||||
<StatusBarItem Grid.Column="2">
|
||||
<TextBlock HorizontalAlignment="Right" TextAlignment="Right" Grid.Column="3" VerticalAlignment="Center">
|
||||
<StatusBar Grid.Row="2" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch">
|
||||
<StatusBar.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
</Grid>
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="0">
|
||||
<TextBlock Text="{Binding HoverLink, ElementName=HoverLinkBehaviour}" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="1" />
|
||||
<StatusBarItem Grid.Column="2">
|
||||
<TextBlock HorizontalAlignment="Right" TextAlignment="Right" Grid.Column="3" VerticalAlignment="Center">
|
||||
Chromium: <Run Text="{Binding Source={x:Static cef:Cef.ChromiumVersion}, Mode=OneTime}" />, CEF: <Run Text="{Binding Source={x:Static cef:Cef.CefVersion}, Mode=OneTime}" />, CefSharp: <Run Text="{Binding Source={x:Static cef:Cef.CefSharpVersion}, Mode=OneTime}"/>, Environment: <Run Text="{Binding Converter={StaticResource EnvironmentConverter}, Mode=OneTime}"/>
|
||||
</TextBlock>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</TextBlock>
|
||||
</StatusBarItem>
|
||||
</StatusBar>
|
||||
</Grid>
|
||||
</DockPanel>
|
||||
</DockPanel>
|
||||
</Window>
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
using System;
|
||||
using AutoLikerCefSharpWpf.Helper;
|
||||
using CefSharp;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
@ -20,9 +23,188 @@ namespace AutoLikerCefSharpWpf
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private const string DefaultUrlForAddedTabs = "https://www.instagram.com/";
|
||||
public string AutoLikerVersion { get; set; }
|
||||
private AutoLikerSettingsManager _alsm;
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
// version
|
||||
this.AutoLikerVersion = "v2.0.0-20230912";
|
||||
this.DataContext = this;
|
||||
// manage settings in UI
|
||||
this._alsm = new AutoLikerSettingsManager(this);
|
||||
|
||||
// Mouse Events
|
||||
Browser.MouseMove += (sender, args) =>
|
||||
{
|
||||
Point position = Mouse.GetPosition(Browser);
|
||||
this.txtMouseX.Text = Convert.ToString(Math.Floor(position.X));
|
||||
this.txtMouseY.Text = Convert.ToString(Math.Floor(position.Y));
|
||||
};
|
||||
|
||||
Browser.JavascriptObjectRepository.ResolveObject += (sender, e) =>
|
||||
{
|
||||
var repo = e.ObjectRepository;
|
||||
if (e.ObjectName == "boundAsync")
|
||||
{
|
||||
BindingOptions bindingOptions = null; //Binding options is an optional param, defaults to null
|
||||
bindingOptions = BindingOptions.DefaultBinder; //Use the default binder to serialize values into complex objects
|
||||
repo.Register("boundAsync", new JavaScriptBoundObject(this), isAsync: true, options: bindingOptions);
|
||||
}
|
||||
};
|
||||
|
||||
Browser.JavascriptObjectRepository.ObjectBoundInJavascript += (sender, e) =>
|
||||
{
|
||||
var name = e.ObjectName;
|
||||
Debug.WriteLine($"Object {e.ObjectName} was bound successfully.");
|
||||
};
|
||||
|
||||
//Wait for the page to finish loading (all resources will have been loaded, rendering is likely still happening)
|
||||
Browser.LoadingStateChanged += (sender, args) =>
|
||||
{
|
||||
//Wait for the Page to finish loading
|
||||
if (args.IsLoading == false)
|
||||
{
|
||||
//Browser.ExecuteScriptAsync("alert('All Resources Have Loaded');");
|
||||
}
|
||||
};
|
||||
|
||||
//Wait for the MainFrame to finish loading
|
||||
Browser.FrameLoadEnd += (sender, args) =>
|
||||
{
|
||||
//Wait for the MainFrame to finish loading
|
||||
if (args.Frame.IsMain)
|
||||
{
|
||||
if (args.Frame.Url.Contains("instagram.com/") && args.Frame.Url.Contains("#al"))
|
||||
{
|
||||
// Bind CEF object
|
||||
string script = @"(async function()
|
||||
{
|
||||
await CefSharp.BindObjectAsync(""boundAsync"");
|
||||
|
||||
//The default is to camel case method names (the first letter of the method name is changed to lowercase)
|
||||
boundAsync.logMessage(""This is a boundAsync test"");
|
||||
console.log('boundAsync worked!');
|
||||
})();";
|
||||
args.Frame.ExecuteJavaScriptAsync(script);
|
||||
|
||||
// Inject JQuery
|
||||
string jq = JavaScriptProcessor.ReturnJavaScriptFromFile("jquery-3.7.1.min.js");
|
||||
args.Frame.ExecuteJavaScriptAsync(jq);
|
||||
|
||||
// Inject AutoLiker class
|
||||
string aljs = JavaScriptProcessor.ReturnJavaScriptFromFile("autotag_injection_min.js");
|
||||
args.Frame.ExecuteJavaScriptAsync(aljs);
|
||||
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
// Execute script
|
||||
string alStartScript = $@"(function()
|
||||
{{
|
||||
if (typeof jQuery == 'undefined') {{
|
||||
console.log('Sorry, but jQuery wasn\'t able to load');
|
||||
}} else {{
|
||||
jQuery.noConflict();
|
||||
console.log('This page is now jQuerified with v' + jQuery.fn.jquery);
|
||||
|
||||
jQuery(document).ready(function () {{
|
||||
requestAnimationFrame(() => {{
|
||||
queueMicrotask(() => {{
|
||||
console.log('finished painting');
|
||||
|
||||
al=new alObject();
|
||||
al.initializeSettings('{this.txtHashTag.Text}',
|
||||
{this.txtMaxLikesMin.Text},
|
||||
{this.txtMaxLikesMax.Text},
|
||||
{this.txtDelayMin.Text},
|
||||
{this.txtDelayMax.Text},
|
||||
{this.txtDelayRestartMin.Text},
|
||||
{this.txtDelayRestartMax.Text});
|
||||
al.instagramStartClickProcess();
|
||||
}});
|
||||
}});
|
||||
}});
|
||||
}}
|
||||
}})();";
|
||||
args.Frame.ExecuteJavaScriptAsync(alStartScript);
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void Button_DevTools(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Browser.ShowDevTools();
|
||||
}
|
||||
|
||||
private void BtnStart_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("==== BtnStart_Click ====");
|
||||
this.LoadInstragramTag();
|
||||
}
|
||||
|
||||
private void BtnStop_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("==== BtnStop_Click ====");
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Debug.WriteLine("*** STOPPING ***");
|
||||
this.LogMessage("Stopping Auto Liking");
|
||||
// reload browser
|
||||
this.Browser.LoadUrl(DefaultUrlForAddedTabs);
|
||||
//this.txtLog.IsReadOnly = false;
|
||||
});
|
||||
}
|
||||
|
||||
private void BtnSaveSettings_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Debug.WriteLine("==== BtnSaveSettings_Click ====");
|
||||
this._alsm.AutoTagSettingsSave();
|
||||
}
|
||||
|
||||
public void LoadInstragramTag()
|
||||
{
|
||||
Debug.WriteLine("==== LoadInstragramTag ====");
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
this.txtLog.Clear();
|
||||
// get hashtag
|
||||
string hashtag = this.txtHashTag.Text;
|
||||
// check if multiple hastags
|
||||
if (hashtag.Contains(","))
|
||||
{
|
||||
string[] hashtags = hashtag.Split(',');
|
||||
int hashtags_length = hashtags.Length;
|
||||
Debug.WriteLine(" - hashtags_length = " + hashtags_length);
|
||||
Random rnd = new Random();
|
||||
int hashtag_index = rnd.Next(hashtags_length);
|
||||
Debug.WriteLine(" - hashtag_index = " + hashtag_index);
|
||||
hashtag = hashtags.GetValue(hashtag_index).ToString().Trim();
|
||||
}
|
||||
this.LogMessage("Load Instagram Tag: " + hashtag);
|
||||
// create URL
|
||||
string URL = "https://www.instagram.com/explore/tags/" + hashtag + "/#al";
|
||||
// reload browser
|
||||
//this.browser.Address = URL;
|
||||
this.Browser.Load(URL);
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Log message in UI text box
|
||||
/// </summary>
|
||||
/// <param name="msg">String message</param>
|
||||
public void LogMessage(string msg)
|
||||
{
|
||||
this.Dispatcher.Invoke(() =>
|
||||
{
|
||||
Debug.WriteLine(msg);
|
||||
this.txtLog.AppendText(msg + Environment.NewLine);
|
||||
this.txtLog.ScrollToEnd();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
106
AutoLikerCefSharpWpf/Properties/Settings.Designer.cs
generated
106
AutoLikerCefSharpWpf/Properties/Settings.Designer.cs
generated
@ -8,23 +8,103 @@
|
||||
// </auto-generated>
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
namespace AutoLikerCefSharpWpf.Properties
|
||||
{
|
||||
|
||||
|
||||
namespace AutoLikerCefSharpWpf.Properties {
|
||||
|
||||
|
||||
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
|
||||
{
|
||||
|
||||
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "17.7.0.0")]
|
||||
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase {
|
||||
|
||||
private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings())));
|
||||
|
||||
public static Settings Default
|
||||
{
|
||||
get
|
||||
{
|
||||
|
||||
public static Settings Default {
|
||||
get {
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("travelphotography,familyphotographer")]
|
||||
public string Instagram_Hashtag {
|
||||
get {
|
||||
return ((string)(this["Instagram_Hashtag"]));
|
||||
}
|
||||
set {
|
||||
this["Instagram_Hashtag"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("45")]
|
||||
public int DelayRestartMin {
|
||||
get {
|
||||
return ((int)(this["DelayRestartMin"]));
|
||||
}
|
||||
set {
|
||||
this["DelayRestartMin"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("60")]
|
||||
public int DelayRestartMax {
|
||||
get {
|
||||
return ((int)(this["DelayRestartMax"]));
|
||||
}
|
||||
set {
|
||||
this["DelayRestartMax"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("10")]
|
||||
public int LikesMin {
|
||||
get {
|
||||
return ((int)(this["LikesMin"]));
|
||||
}
|
||||
set {
|
||||
this["LikesMin"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("25")]
|
||||
public int LikesMax {
|
||||
get {
|
||||
return ((int)(this["LikesMax"]));
|
||||
}
|
||||
set {
|
||||
this["LikesMax"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("5")]
|
||||
public int DelayMin {
|
||||
get {
|
||||
return ((int)(this["DelayMin"]));
|
||||
}
|
||||
set {
|
||||
this["DelayMin"] = value;
|
||||
}
|
||||
}
|
||||
|
||||
[global::System.Configuration.UserScopedSettingAttribute()]
|
||||
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
|
||||
[global::System.Configuration.DefaultSettingValueAttribute("15")]
|
||||
public int DelayMax {
|
||||
get {
|
||||
return ((int)(this["DelayMax"]));
|
||||
}
|
||||
set {
|
||||
this["DelayMax"] = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,7 +1,27 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
<SettingsFile xmlns="uri:settings" CurrentProfile="(Default)">
|
||||
<Profiles>
|
||||
<Profile Name="(Default)" />
|
||||
</Profiles>
|
||||
<Settings />
|
||||
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="AutoLikerCefSharpWpf.Properties" GeneratedClassName="Settings">
|
||||
<Profiles />
|
||||
<Settings>
|
||||
<Setting Name="Instagram_Hashtag" Type="System.String" Scope="User">
|
||||
<Value Profile="(Default)">travelphotography,familyphotographer</Value>
|
||||
</Setting>
|
||||
<Setting Name="DelayRestartMin" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">45</Value>
|
||||
</Setting>
|
||||
<Setting Name="DelayRestartMax" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">60</Value>
|
||||
</Setting>
|
||||
<Setting Name="LikesMin" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">10</Value>
|
||||
</Setting>
|
||||
<Setting Name="LikesMax" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">25</Value>
|
||||
</Setting>
|
||||
<Setting Name="DelayMin" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">5</Value>
|
||||
</Setting>
|
||||
<Setting Name="DelayMax" Type="System.Int32" Scope="User">
|
||||
<Value Profile="(Default)">15</Value>
|
||||
</Setting>
|
||||
</Settings>
|
||||
</SettingsFile>
|
||||
28
AutoLikerCefSharpWpf/Settings.cs
Normal file
28
AutoLikerCefSharpWpf/Settings.cs
Normal file
@ -0,0 +1,28 @@
|
||||
namespace AutoLikerCefSharpWpf.Properties {
|
||||
|
||||
|
||||
// This class allows you to handle specific events on the settings class:
|
||||
// The SettingChanging event is raised before a setting's value is changed.
|
||||
// The PropertyChanged event is raised after a setting's value is changed.
|
||||
// The SettingsLoaded event is raised after the setting values are loaded.
|
||||
// The SettingsSaving event is raised before the setting values are saved.
|
||||
internal sealed partial class Settings {
|
||||
|
||||
public Settings() {
|
||||
// // To add event handlers for saving and changing settings, uncomment the lines below:
|
||||
//
|
||||
// this.SettingChanging += this.SettingChangingEventHandler;
|
||||
//
|
||||
// this.SettingsSaving += this.SettingsSavingEventHandler;
|
||||
//
|
||||
}
|
||||
|
||||
private void SettingChangingEventHandler(object sender, System.Configuration.SettingChangingEventArgs e) {
|
||||
// Add code to handle the SettingChangingEvent event here.
|
||||
}
|
||||
|
||||
private void SettingsSavingEventHandler(object sender, System.ComponentModel.CancelEventArgs e) {
|
||||
// Add code to handle the SettingsSaving event here.
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user